refactor(xslt): keep ResultItem/XSLTContext file-private for namespacing

Only the static deduplicated helper moves to XSLTElements.swift (it needs
no private types); attributeSetAttributes stays in the transformer so the
evaluation context and result-item types remain file-private, satisfying
the one-file-scope-type namespacing gate.
This commit is contained in:
Mihaela Mihaljevic 2026-06-09 01:41:48 +02:00
parent 75ed549c33
commit 21ed15b1ec
2 changed files with 19 additions and 21 deletions

View File

@ -1,18 +1,4 @@
extension PureXML.XSLT.Transformer {
/// The attributes contributed by `names` and the attribute sets they include,
/// lower precedence first, with a `visiting` guard against recursive includes.
func attributeSetAttributes(_ names: [String], _ context: XSLTContext, visiting: Set<String>) -> [PureXML.Model.Attribute] {
var result: [PureXML.Model.Attribute] = []
for name in names where !visiting.contains(name) {
guard let set = stylesheet.attributeSets[name] else { continue }
result += attributeSetAttributes(set.use, context, visiting: visiting.union([name]))
for item in instantiate(set.attributes, context) {
if case let .attribute(attribute) = item { result.append(attribute) }
}
}
return result
}
/// The attributes with duplicates by name removed, keeping the last (so a
/// later attribute overrides one from an attribute set or an earlier source).
static func deduplicated(_ attributes: [PureXML.Model.Attribute]) -> [PureXML.Model.Attribute] {

View File

@ -1,14 +1,12 @@
/// One produced item: a node for the result tree, or an attribute to attach to
/// the enclosing element. Module-internal so the transformer's helpers can span
/// files.
enum ResultItem {
/// the enclosing element. File-scope and private.
private enum ResultItem {
case node(PureXML.Model.Node)
case attribute(PureXML.Model.Attribute)
}
/// The evaluation context during instantiation. Module-internal so the
/// transformer's helpers can span files.
struct XSLTContext {
/// The evaluation context during instantiation. File-scope and private.
private struct XSLTContext {
var node: PureXML.Model.TreeNode
var position: Int
var size: Int
@ -133,7 +131,7 @@ extension PureXML.XSLT {
// MARK: Instantiation
func instantiate(_ body: [Instruction], _ context: XSLTContext) -> [ResultItem] {
fileprivate func instantiate(_ body: [Instruction], _ context: XSLTContext) -> [ResultItem] {
var items: [ResultItem] = []
var context = context
for instruction in body {
@ -341,6 +339,20 @@ extension PureXML.XSLT.Transformer {
return .node(.element(.init(name: name, attributes: Self.deduplicated(attributes), children: children)))
}
/// The attributes contributed by `names` and the attribute sets they include,
/// lower precedence first, with a `visiting` guard against recursive includes.
private func attributeSetAttributes(_ names: [String], _ context: XSLTContext, visiting: Set<String>) -> [PureXML.Model.Attribute] {
var result: [PureXML.Model.Attribute] = []
for name in names where !visiting.contains(name) {
guard let set = stylesheet.attributeSets[name] else { continue }
result += attributeSetAttributes(set.use, context, visiting: visiting.union([name]))
for item in instantiate(set.attributes, context) {
if case let .attribute(attribute) = item { result.append(attribute) }
}
}
return result
}
private func avt(_ template: PureXML.XSLT.ValueTemplate, _ context: XSLTContext) -> String {
template.reduce(into: "") { result, part in
switch part {