Repository: servo/servo
File: components/devtools/actors/source.rs (Rust)

Code before:
                        .insert(entry.column_number - 1);
                }
                let reply = GetBreakpointPositionsCompressedReply {
                    from: self.name(),
                    positions,
                };
                request.reply_final(&reply)?
            },
            _ => return Err(ActorError::UnrecognizedPacketType),
        };
        Ok(())
    }
}

impl SourceActor {
    pub fn find_offset(&self, column: u32, line: u32) -> u32 {
        let (tx, rx) = channel().unwrap();
        self.script_sender
            .send(DevtoolScriptControlMsg::GetPossibleBreakpoints(
                self.spidermonkey_id,
                tx,
            ))
            .unwrap();
        let result = rx.recv().unwrap();
        for entry in result {
            if entry.line_number == line && entry.column_number - 1 == column {
                return entry.offset;
            }
        }
        panic!("There should be an entry with this column and line numbers");
    }
}


Review comment (suggestion):
I would add a comment here about calculating correct offset that is always `column_number - 1` same as we calculate in `getBreakpointPositionsCompressed`. It took us a moment and a panic to realize that 😅

Code after:
                        self.spidermonkey_id,
                        tx,
                    ))
                    .map_err(|_| ActorError::Internal)?;
                let result = rx.recv().map_err(|_| ActorError::Internal)?;

                let mut positions: BTreeMap<u32, BTreeSet<u32>> = BTreeMap::default();
                for location in result {
                    // Line number are one-based. Column numbers are zero-based.
                    // FIXME: the docs say column numbers are one-based, but this appears to be incorrect.
                    // <https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#source-locations>
                    if location.line_number < start.line || location.line_number > end.line {
                        continue;
                    }
                    positions
                        .entry(location.line_number)
                        .or_default()
                        .insert(location.column_number - 1);
                }
                let reply = GetBreakpointPositionsCompressedReply {
                    from: self.name(),
                    positions,
                };
                request.reply_final(&reply)?
            },
            _ => return Err(ActorError::UnrecognizedPacketType),
        };
        Ok(())
    }
}

impl SourceActor {
    pub fn find_offset(&self, line: u32, column: u32) -> (u32, u32) {
        let (tx, rx) = channel().unwrap();
        self.script_sender
            .send(DevtoolScriptControlMsg::GetPossibleBreakpoints(
                self.spidermonkey_id,
                tx,
            ))
            .unwrap();
        let result = rx.recv().unwrap();
        for location in result {
            // Line number are one-based. Column numbers are zero-based.
            // FIXME: the docs say column numbers are one-based, but this appears to be incorrect.
            // <https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#source-locations>
            if location.line_number == line && location.column_number - 1 == column {
                return (location.script_id, location.offset);
            }
        }
        panic!("There should be an entry with this column and line numbers");
    }