/* * Copyright (c) 2022-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include namespace JS { class JS_API SourceCode : public RefCounted { public: static NonnullRefPtr create(String filename, Utf16String code); static NonnullRefPtr create(String filename, size_t length_in_code_units, String source_encoding, Core::ImmutableBytes source_bytes); String const& filename() const { return m_filename; } Utf16String const& code() const; Utf16View const& code_view() const; size_t length_in_code_units() const { return m_length_in_code_units; } u16 const* utf16_data() const; Utf16String source_text_from_offsets(size_t start_offset, size_t length) const; SourceRange range_from_offsets(u32 start_offset, u32 end_offset) const; private: SourceCode(String filename, Utf16String code); SourceCode(String filename, size_t length_in_code_units, String source_encoding, Core::ImmutableBytes source_bytes); void ensure_code() const; Utf16String decode_source_range(size_t start_offset, size_t length) const; bool source_bytes_can_be_sliced_by_code_unit_offsets() const; Optional source_text_from_utf8_source_bytes(size_t start_offset, size_t length) const; bool ensure_utf8_source_byte_spans() const; Optional byte_offset_for_utf8_code_unit_offset(size_t code_unit_offset) const; struct Utf8SourceByteSpan { size_t code_unit_offset { 0 }; size_t code_unit_length { 0 }; size_t byte_offset { 0 }; size_t byte_length { 0 }; }; String m_filename; Optional mutable m_code; String m_source_encoding; Core::ImmutableBytes mutable m_source_bytes; Utf16View mutable m_code_view; size_t m_length_in_code_units { 0 }; // For fast mapping of offsets to line/column numbers, we build a list of // starting points (with byte offsets into the source string) and which // line:column they map to. This can then be binary-searched. void fill_position_cache() const; struct CachedPosition { Position position; u32 offset { 0 }; }; Vector mutable m_cached_positions; // Cached UTF-16 widening of ASCII source data, lazily populated by // utf16_data() for use by the Rust compilation pipeline. Vector mutable m_utf16_data_cache; Optional mutable m_source_bytes_can_be_sliced_by_code_unit_offsets; Vector mutable m_utf8_source_byte_spans; size_t mutable m_utf8_source_byte_span_initial_byte_offset { 0 }; bool mutable m_tried_to_build_utf8_source_byte_spans { false }; bool mutable m_can_use_utf8_source_byte_spans { false }; }; }