docs(frontend): explain parsing entry points and source diagnostics
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
//! Reader 产生 SourceUnit,lexer/parser/compiler 借用其文本;错误在 annotate 时固化来源及行列。
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
@@ -7,15 +8,22 @@ use crate::{Diagnostic, SourceLocation};
|
||||
/// Source provenance, independent of filesystem layout or VM heap handles.
|
||||
/// Endor revisions are opaque labels supplied by the host, not verified hashes.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
/// Reader 选择的来源身份,诊断和代码文件名显示使用;Endor revision 是宿主标签,不代表已验证哈希。
|
||||
pub enum SourceOrigin {
|
||||
// 内存文本的宿主显示名,不表示磁盘路径。
|
||||
Text { name: String },
|
||||
// 已读到 EOF 的字节流显示名,流本身不再存于快照。
|
||||
Stream { name: String },
|
||||
// 实际读取时保存的路径,不要求规范化为绝对路径。
|
||||
File { path: PathBuf },
|
||||
// 经宿主解析的 URI 与所选版本身份,前端不推断其命名空间或哈希算法。
|
||||
Endor { uri: String, revision: String },
|
||||
}
|
||||
|
||||
impl fmt::Display for SourceOrigin {
|
||||
/// 诊断与生成代码文件名调用 Display,按来源种类生成可读身份文本。
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// 文本/流显示名称,文件显示路径,Endor 来源附带版本标签。
|
||||
match self {
|
||||
Self::Text { name } | Self::Stream { name } => formatter.write_str(name),
|
||||
Self::File { path } => write!(formatter, "{}", path.display()),
|
||||
@@ -27,25 +35,33 @@ impl fmt::Display for SourceOrigin {
|
||||
/// An owned, immutable UTF-8 snapshot. Reader adapters preserve the text exactly
|
||||
/// so token byte offsets still refer to the original decoded source.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
/// EndorReader 构造的拥有型 UTF-8 快照;原文不规范化,以保持 Token 和 AST 字节跨度对应原输入。
|
||||
pub struct SourceUnit {
|
||||
// 来源身份与文本一起保存,供错误和代码元数据使用。
|
||||
origin: SourceOrigin,
|
||||
// 已验证 UTF-8 的原始文本,解析阶段只借用它,不修改换行或空白。
|
||||
text: String,
|
||||
}
|
||||
|
||||
impl SourceUnit {
|
||||
/// Reader 适配器完成解码后调用;将来源及文本移入快照,不再读取外部数据。
|
||||
pub(crate) fn new(origin: SourceOrigin, text: String) -> Self {
|
||||
Self { origin, text }
|
||||
}
|
||||
|
||||
/// 编译器生成文件名、宿主检查来源时借用身份,保留 Endor 的已解析版本。
|
||||
pub fn origin(&self) -> &SourceOrigin {
|
||||
&self.origin
|
||||
}
|
||||
|
||||
/// lexer/parser/compiler 及位置校验借用 UTF-8 文本,返回生命周期依附当前快照。
|
||||
pub fn text(&self) -> &str {
|
||||
&self.text
|
||||
}
|
||||
|
||||
/// Bind a diagnostic to this snapshot before discarding its source buffer.
|
||||
/// lex_source、parse_source 系列及 compile_source 在失败时调用,把字节诊断绑定到此来源和行列。
|
||||
/// 返回值保存来源、位置及原诊断,不保存源码全文;后续无需再次读源即可显示基本错误。
|
||||
pub fn annotate(&self, diagnostic: Diagnostic) -> SourceDiagnostic {
|
||||
SourceDiagnostic {
|
||||
location: diagnostic.location(&self.text),
|
||||
@@ -56,13 +72,18 @@ impl SourceUnit {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
/// 带来源及预计算位置的阶段错误,由 SourceUnit::annotate 创建,交给宿主显示或追查底层 Diagnostic。
|
||||
pub struct SourceDiagnostic {
|
||||
// 错误对应的来源,独立于原快照生命周期。
|
||||
pub origin: SourceOrigin,
|
||||
// annotate 当时根据原文计算的一基行列,后续 Display 不重新计算。
|
||||
pub location: SourceLocation,
|
||||
// 原始字节跨度、阶段、说明及期望项,保留给程序化处理与 Error::source。
|
||||
pub diagnostic: Box<Diagnostic>,
|
||||
}
|
||||
|
||||
impl fmt::Display for SourceDiagnostic {
|
||||
/// 宿主显示错误时输出“来源:行:列:说明”,跨度及期望项仍可从 diagnostic 单独读取。
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
formatter,
|
||||
@@ -73,6 +94,7 @@ impl fmt::Display for SourceDiagnostic {
|
||||
}
|
||||
|
||||
impl Error for SourceDiagnostic {
|
||||
/// 标准错误链使用者调用,暴露原始阶段诊断作为本错误的直接原因。
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
Some(self.diagnostic.as_ref())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user