Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
953 changes: 905 additions & 48 deletions crates/html/src/conformance/execution.rs

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions crates/html/src/conformance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ pub use crate::html5::shared::{
ParserGuardrail, ParserGuardrailPayload, ParserRecoveryAction, ParserResourceLimit,
ParserResourceLimitPayload, ParserStage, ParserTokenKind, PositionUnavailableReason,
SourceBytePosition, SourcePositionUnavailableReason, TokenizerExtensionParseErrorCode,
TreeConstructionImplementationDiagnosticCode, TreeConstructionParseErrorCode,
Utf8ReplacementPayload, Utf8ReplacementReason, WhatwgParseErrorCode,
TransitionTokenSummary, TreeConstructionImplementationDiagnosticCode,
TreeConstructionParseErrorCode, TreeConstructionUnsupportedFeature, TreeDispatchPath,
TreeTransitionEvent, UnsupportedFeatureEvent, Utf8ReplacementPayload, Utf8ReplacementReason,
WhatwgParseErrorCode,
};
pub use execution::{
ObservationRequest, ObservationReservationSite, ObservationResourceExhaustion,
ParserObservationExecutionError, ParserObservationInput, ParserObservationInvariantError,
ParserObservationRequest, ParserObservationTarget, ParserTokenizerInvariantError,
ScalarObservationRequest, execute_parser_observation,
ScalarObservationRequest, UnsupportedFeatureObservationInvariantError,
execute_parser_observation,
};
pub use model::*;
50 changes: 2 additions & 48 deletions crates/html/src/conformance/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//! public web-platform API and are available only with `parser-conformance`.

use crate::html5::shared::{
ImplementationDiagnosticEvent, ObservedInsertionMode, ObservedToken, ParseErrorEvent,
ParserContextSummary,
ImplementationDiagnosticEvent, ObservedToken, ParseErrorEvent, TreeTransitionEvent,
UnsupportedFeatureEvent,
};
use crate::{AttributeNamespace, DocumentMode, ElementNamespace};

Expand Down Expand Up @@ -199,52 +199,6 @@ pub enum ObservedPatchOperation {
},
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TreeDispatchPath {
HtmlInsertionMode(ObservedInsertionMode),
SharedTemplateRules,
ForeignContent,
TextMode,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TransitionTokenSummary {
Doctype,
StartTag { name: String, self_closing: bool },
EndTag { name: String },
Character { data: String },
Comment,
ProcessingInstruction { target: String },
Eof,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TreeTransitionEvent {
pub occurrence: u64,
pub token: TransitionTokenSummary,
pub insertion_mode_before: ObservedInsertionMode,
pub dispatch_path: TreeDispatchPath,
pub insertion_mode_after: ObservedInsertionMode,
pub reprocessed: bool,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UnsupportedFeatureEvent {
pub occurrence: u64,
pub classification: UnsupportedFeatureClassification,
pub context: Option<ParserContextSummary>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum UnsupportedFeatureClassification {
UnsupportedInputPreprocessingBranch,
UnsupportedTokenizerBranch,
UnsupportedTreeConstructionRule,
DeferredFragmentParsing,
DeferredScriptingDependentParsing,
PartialForeignContentBranch,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParserFinalizationReport {
pub input: InputFinalizationChecks,
Expand Down
4 changes: 2 additions & 2 deletions crates/html/src/html5/session/tests/text_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ fn parser_observations_do_not_change_text_mode_tokenizer_controls() {
tokens: SurfaceCaptureRequest::Capture { capacity: 64 },
parse_errors: SurfaceCaptureRequest::Capture { capacity: 64 },
implementation_diagnostics: SurfaceCaptureRequest::Capture { capacity: 64 },
..ParserObservationConfig::default()
},
)
} else {
Expand Down Expand Up @@ -212,8 +213,7 @@ fn parser_observations_do_not_change_text_mode_tokenizer_controls() {
assert_eq!(observed.document_mode, unobserved.document_mode);

let capture = observed.capture.expect("explicit observation capture");
assert_eq!(capture.invariant, None);
assert!(!capture.token_capture_failed);
assert_eq!(capture.failure, None);
assert_eq!(capture.tokens.dropped, 0);
assert_eq!(capture.parse_errors.dropped, 0);
assert_eq!(capture.implementation_diagnostics.dropped, 0);
Expand Down
29 changes: 18 additions & 11 deletions crates/html/src/html5/shared/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::ParserFailureInjection;
use super::ParserObservationCapture;
use super::{
AtomTable, Counters, ErrorOrigin, ErrorPolicy, Input, LegacyParseErrorCode,
NormalizedPositionIndex, ParseError, ParseErrorCode, ParserDiagnosticSink, ParserGuardrail,
NormalizedPositionIndex, ParseError, ParseErrorCode, ParserEventSink, ParserGuardrail,
ParserObservationConfig, ParserObservationRecorder, ParserRecoveryAction, ParserResourceLimit,
ParserStage, Utf8ReplacementPayload, Utf8ReplacementReason, WhatwgParseErrorCode,
};
Expand Down Expand Up @@ -174,7 +174,7 @@ impl DocumentParseContext {
legacy_aux: Option<u32>,
legacy_code_override: Option<LegacyParseErrorCode>,
) {
let mut sink = ParserDiagnosticSink::new(
let mut sink = ParserEventSink::new(
&mut self.counters,
self.error_policy,
&mut self.errors,
Expand Down Expand Up @@ -206,7 +206,7 @@ impl DocumentParseContext {
position: usize,
description: Option<&'static str>,
) {
let mut sink = ParserDiagnosticSink::new(
let mut sink = ParserEventSink::new(
&mut self.counters,
self.error_policy,
&mut self.errors,
Expand Down Expand Up @@ -236,7 +236,7 @@ impl DocumentParseContext {
position: usize,
description: Option<&'static str>,
) {
let mut sink = ParserDiagnosticSink::new(
let mut sink = ParserEventSink::new(
&mut self.counters,
self.error_policy,
&mut self.errors,
Expand Down Expand Up @@ -265,7 +265,7 @@ impl DocumentParseContext {
reason: Utf8ReplacementReason,
payload: Utf8ReplacementPayload,
) {
let mut sink = ParserDiagnosticSink::new(
let mut sink = ParserEventSink::new(
&mut self.counters,
self.error_policy,
&mut self.errors,
Expand Down Expand Up @@ -309,6 +309,7 @@ impl DocumentParseContext {
implementation_diagnostics: super::SurfaceCaptureRequest::Capture {
capacity: 4_096,
},
..ParserObservationConfig::default()
});
}
}
Expand Down Expand Up @@ -517,8 +518,10 @@ mod tests {
let parse_capture = parse_ctx.take_observations().expect("parse capture");
assert!(parse_capture.parse_errors.items.is_empty());
assert_eq!(
parse_capture.invariant,
Some(crate::html5::shared::ParserObservationInvariant::NormalizedPositionIndexMissing)
parse_capture.failure,
Some(crate::html5::shared::ParserObservationFailure::Invariant(
crate::html5::shared::ParserObservationInvariant::NormalizedPositionIndexMissing
))
);

let mut diagnostic_ctx = observed_context(0, 1);
Expand All @@ -540,8 +543,10 @@ mod tests {
.is_empty()
);
assert_eq!(
diagnostic_capture.invariant,
Some(crate::html5::shared::ParserObservationInvariant::NormalizedPositionIndexMissing)
diagnostic_capture.failure,
Some(crate::html5::shared::ParserObservationFailure::Invariant(
crate::html5::shared::ParserObservationInvariant::NormalizedPositionIndexMissing
))
);
}

Expand Down Expand Up @@ -802,8 +807,10 @@ mod tests {
assert!(capture.parse_errors.items.is_empty());
assert!(capture.implementation_diagnostics.items.is_empty());
assert_eq!(
capture.invariant,
Some(super::super::ParserObservationInvariant::InvalidNormalizedPositionOffset)
capture.failure,
Some(super::super::ParserObservationFailure::Invariant(
super::super::ParserObservationInvariant::InvalidNormalizedPositionOffset
))
);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Shared parser-owned diagnostic fanout.
//! Shared parser-owned diagnostic and semantic-observation fanout.

use super::{
Counters, DiagnosticEventMetadata, ErrorOrigin, ErrorPolicy, EventPosition,
Expand All @@ -7,7 +7,8 @@ use super::{
ParseErrorEvent, ParserContextSummary, ParserGuardrail, ParserGuardrailPayload,
ParserObservationRecorder, ParserRecoveryAction, ParserResourceLimit,
ParserResourceLimitPayload, ParserStage, PositionUnavailableReason,
TreeConstructionImplementationDiagnosticCode, Utf8ReplacementPayload, Utf8ReplacementReason,
TreeConstructionImplementationDiagnosticCode, TreeTransitionEvent, UnsupportedFeatureEvent,
UnsupportedFeatureObservationFailure, Utf8ReplacementPayload, Utf8ReplacementReason,
};
use std::collections::VecDeque;

Expand All @@ -20,14 +21,14 @@ pub(crate) struct LegacyDiagnosticProjection {
pub(crate) aux: Option<u32>,
}

pub(crate) struct ParserDiagnosticSink<'a> {
pub(crate) struct ParserEventSink<'a> {
counters: &'a mut Counters,
error_policy: ErrorPolicy,
errors: &'a mut Option<VecDeque<ParseError>>,
observations: &'a mut Option<ParserObservationRecorder>,
}

impl<'a> ParserDiagnosticSink<'a> {
impl<'a> ParserEventSink<'a> {
pub(crate) fn new(
counters: &'a mut Counters,
error_policy: ErrorPolicy,
Expand Down Expand Up @@ -307,6 +308,51 @@ impl<'a> ParserDiagnosticSink<'a> {
);
}

pub(crate) fn reserve_tree_transition(&mut self) -> Option<u64> {
self.observations
.as_mut()
.and_then(ParserObservationRecorder::reserve_tree_transition)
}

pub(crate) fn retain_tree_transition(&mut self, event: TreeTransitionEvent) {
if let Some(recorder) = self.observations.as_mut() {
recorder.retain_tree_transition(event);
}
}

pub(crate) fn record_tree_transition_capture_failure(&mut self) {
if let Some(recorder) = self.observations.as_mut() {
recorder.record_tree_transition_capture_failure();
}
}

pub(crate) fn unsupported_features_requested(&self) -> bool {
self.observations
.as_ref()
.is_some_and(ParserObservationRecorder::unsupported_features_requested)
}

pub(crate) fn reserve_unsupported_feature(&mut self) -> Option<u64> {
self.observations
.as_mut()
.and_then(ParserObservationRecorder::reserve_unsupported_feature)
}

pub(crate) fn retain_unsupported_feature(&mut self, event: UnsupportedFeatureEvent) {
if let Some(recorder) = self.observations.as_mut() {
recorder.retain_unsupported_feature(event);
}
}

pub(crate) fn record_unsupported_feature_observation_failure(
&mut self,
failure: UnsupportedFeatureObservationFailure,
) {
if let Some(recorder) = self.observations.as_mut() {
recorder.record_unsupported_feature_observation_failure(failure);
}
}

fn record_implementation_diagnostic_known(
&mut self,
input: &Input,
Expand Down
9 changes: 5 additions & 4 deletions crates/html/src/html5/shared/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
mod atom;
mod context;
mod counters;
mod diagnostics;
mod error;
mod event_sink;
mod input;
mod observation;
mod observation_model;
Expand All @@ -18,22 +18,23 @@ mod token;
pub use atom::{AtomError, AtomId, AtomTable};
pub use context::DocumentParseContext;
pub use counters::Counters;
pub(crate) use diagnostics::{LegacyDiagnosticProjection, ParserDiagnosticSink};
#[allow(unused_imports)]
pub use error::{
EngineInvariantError, ErrorOrigin, ErrorPolicy, Html5SessionError, LegacyParseErrorCode,
ParseError, ParserFatalError, ParserReservationSite, ParserResourceExhaustion,
};
pub(crate) use event_sink::{LegacyDiagnosticProjection, ParserEventSink};
#[allow(unused_imports)]
pub use input::{ByteStreamDecoder, DecodeResult, Input};
#[cfg(any(test, feature = "parser-conformance"))]
pub(crate) use observation::{
CapturedSurface, ObservationOccurrenceSequence, ObservationSurface, ParserObservationCapture,
ParserObservationInvariant, SurfaceCaptureRequest,
ParserObservationCaptureFailure, ParserObservationFailure, ParserObservationInvariant,
SurfaceCaptureRequest,
};
pub(crate) use observation::{
NormalizedPositionIndex, ObservationPositionResolution, ObservationPositionSource,
ParserObservationConfig, ParserObservationRecorder,
ParserObservationConfig, ParserObservationRecorder, UnsupportedFeatureObservationFailure,
};
pub use observation_model::*;
#[cfg(all(
Expand Down
Loading
Loading