| // Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #if !defined(DART_PRECOMPILED_RUNTIME) || defined(DART_DYNAMIC_MODULES) | |
| #include "vm/line_starts_reader.h" | |
| #include "vm/object.h" | |
| #include "vm/token_position.h" | |
| namespace dart { | |
| LineStartsReader::LineStartsReader(const dart::TypedData& line_starts_data) | |
| : line_starts_data_(line_starts_data), | |
| element_type_(line_starts_data.ElementType()) { | |
| RELEASE_ASSERT((element_type_ == kUint16ArrayElement) || | |
| (element_type_ == kUint32ArrayElement)); | |
| } | |
| uint32_t LineStartsReader::MaxPosition() const { | |
| const intptr_t line_count = line_starts_data_.Length(); | |
| if (line_count == 0) { | |
| return 0; | |
| } | |
| return At(line_count - 1); | |
| } | |
| bool LineStartsReader::LocationForPosition(intptr_t position, | |
| intptr_t* line, | |
| intptr_t* col) const { | |
| const intptr_t line_count = line_starts_data_.Length(); | |
| if (position < 0 || static_cast<uint32_t>(position) > MaxPosition() || | |
| line_count == 0) { | |
| return false; | |
| } | |
| intptr_t lo = 0; | |
| intptr_t hi = line_count; | |
| while (hi > lo + 1) { | |
| const intptr_t mid = lo + (hi - lo) / 2; | |
| const intptr_t mid_position = At(mid); | |
| if (mid_position > position) { | |
| hi = mid; | |
| } else { | |
| lo = mid; | |
| } | |
| } | |
| *line = lo + 1; | |
| if (col != nullptr) { | |
| *col = position - At(lo) + 1; | |
| } | |
| return true; | |
| } | |
| bool LineStartsReader::TokenRangeAtLine(intptr_t line_number, | |
| TokenPosition* first_token_index, | |
| TokenPosition* last_token_index) const { | |
| const intptr_t line_count = line_starts_data_.Length(); | |
| if (line_number <= 0 || line_number > line_count) { | |
| return false; | |
| } | |
| *first_token_index = TokenPosition::Deserialize(At(line_number - 1)); | |
| if (line_number == line_count) { | |
| *last_token_index = *first_token_index; | |
| } else { | |
| *last_token_index = TokenPosition::Deserialize(At(line_number) - 1); | |
| } | |
| return true; | |
| } | |
| } // namespace dart | |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) || defined(DART_DYNAMIC_MODULES) |