1 /** 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "sourceLocation.h" 17 18 #include "lexer/token/letters.h" 19 20 #include <cstdint> 21 22 namespace ark::es2panda::lexer { AddCol(size_t offset)23void OffsetEntry::AddCol(size_t offset) 24 { 25 size_t diff = offset - offset_; 26 offset_ = offset; 27 28 if (ranges.empty()) { 29 ranges.emplace_back(Range {diff}); 30 return; 31 } 32 33 auto &range = ranges.back(); 34 35 if (diff == range.byteSize) { 36 range.cnt++; 37 } else { 38 ranges.emplace_back(Range {diff}); 39 } 40 } 41 LineIndex(const util::StringView & source)42LineIndex::LineIndex(const util::StringView &source) noexcept 43 { 44 auto iter = util::StringView::Iterator(source); 45 entries_.emplace_back(0); 46 47 while (true) { 48 switch (iter.Next()) { 49 case util::StringView::Iterator::INVALID_CP: { 50 return; 51 } 52 case LEX_CHAR_CR: { 53 if (iter.HasNext() && iter.Peek() == LEX_CHAR_LF) { 54 iter.Forward(1); 55 } 56 57 [[fallthrough]]; 58 } 59 case LEX_CHAR_LF: 60 case LEX_CHAR_PS: 61 case LEX_CHAR_LS: { 62 entries_.emplace_back(iter.Index()); 63 break; 64 } 65 default: { 66 entries_.back().AddCol(iter.Index()); 67 } 68 } 69 } 70 } 71 GetLocation(SourcePosition pos) const72SourceLocation LineIndex::GetLocation(SourcePosition pos) const noexcept 73 { 74 size_t line = pos.line; 75 76 size_t col = 0; 77 78 // It can occur during stdlib parsing where entries does not uploaded 79 if (line > entries_.size()) { 80 return SourceLocation(line + 1, col + 1); 81 } 82 83 if (line == entries_.size()) { 84 --line; 85 } 86 87 const auto &entry = entries_[line]; 88 size_t diff = pos.index - entry.lineStart; 89 90 for (const auto &range : entry.ranges) { 91 if (diff < range.cnt) { 92 col += diff; 93 break; 94 } 95 96 diff -= range.cnt * range.byteSize; 97 col += range.cnt; 98 } 99 100 return SourceLocation(line + 1, col + 1); 101 } 102 } // namespace ark::es2panda::lexer 103