@tradik/xslt3 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +28 -0
- package/README.md +98 -2
- package/package.json +43 -4
- package/src/errors.js +20 -0
- package/src/functions/aggregates.js +144 -0
- package/src/functions/arraySort.js +33 -0
- package/src/functions/arrays.js +181 -0
- package/src/functions/attributeTypes.js +58 -0
- package/src/functions/baseUris.js +82 -0
- package/src/functions/collations.js +127 -0
- package/src/functions/collections.js +84 -0
- package/src/functions/context.js +83 -0
- package/src/functions/core.js +167 -0
- package/src/functions/datetime.js +203 -0
- package/src/functions/deepEqual.js +132 -0
- package/src/functions/diagnostics.js +88 -0
- package/src/functions/focus.js +34 -0
- package/src/functions/format/dateComponents.js +176 -0
- package/src/functions/format/datePicture.js +115 -0
- package/src/functions/format/decimalFormat.js +65 -0
- package/src/functions/format/digitPattern.js +145 -0
- package/src/functions/format/formatDateTime.js +204 -0
- package/src/functions/format/formatInteger.js +109 -0
- package/src/functions/format/formatNumber.js +165 -0
- package/src/functions/format/fractionFormat.js +80 -0
- package/src/functions/format/germanWords.js +89 -0
- package/src/functions/format/numberLanguages.js +41 -0
- package/src/functions/format/numberPicture.js +202 -0
- package/src/functions/format/numberWords.js +155 -0
- package/src/functions/format/place.js +74 -0
- package/src/functions/format/timezoneFormat.js +89 -0
- package/src/functions/higherOrder.js +106 -0
- package/src/functions/ids.js +127 -0
- package/src/functions/json/index.js +17 -0
- package/src/functions/json/jsonChars.js +110 -0
- package/src/functions/json/jsonParser.js +203 -0
- package/src/functions/json/jsonStrings.js +116 -0
- package/src/functions/json/jsonToXml.js +116 -0
- package/src/functions/json/parseJson.js +119 -0
- package/src/functions/json/xmlRepresentation.js +103 -0
- package/src/functions/json/xmlToJson.js +147 -0
- package/src/functions/library.js +47 -0
- package/src/functions/mapArrayEqual.js +41 -0
- package/src/functions/maps.js +152 -0
- package/src/functions/math.js +73 -0
- package/src/functions/nodePaths.js +181 -0
- package/src/functions/nodes.js +199 -0
- package/src/functions/numeric.js +148 -0
- package/src/functions/options.js +58 -0
- package/src/functions/parseIetfDate.js +104 -0
- package/src/functions/parseXml.js +77 -0
- package/src/functions/qnames.js +68 -0
- package/src/functions/random.js +128 -0
- package/src/functions/regex/analyzeString.js +144 -0
- package/src/functions/regex/charClass.js +112 -0
- package/src/functions/regex/compile.js +81 -0
- package/src/functions/regex/escapes.js +109 -0
- package/src/functions/regex/parser.js +169 -0
- package/src/functions/regex/reader.js +37 -0
- package/src/functions/regex/regexFunctions.js +140 -0
- package/src/functions/regex/translate.js +102 -0
- package/src/functions/regex/unicodeBlocks.js +194 -0
- package/src/functions/registry.js +140 -0
- package/src/functions/sequences.js +173 -0
- package/src/functions/serializeFunction.js +53 -0
- package/src/functions/signatures.js +105 -0
- package/src/functions/sort.js +102 -0
- package/src/functions/stringMatch.js +45 -0
- package/src/functions/strings.js +194 -0
- package/src/functions/stringsCore.js +66 -0
- package/src/functions/support.js +106 -0
- package/src/functions/textDecoding.js +117 -0
- package/src/functions/ucaCollation.js +127 -0
- package/src/functions/unparsedText.js +71 -0
- package/src/functions/uri.js +166 -0
- package/src/functions/xqueryModule.js +24 -0
- package/src/index.js +38 -0
- package/src/items/array.js +84 -0
- package/src/items/function.js +45 -0
- package/src/items/map.js +120 -0
- package/src/items/mapKey.js +82 -0
- package/src/serialize/index.js +129 -0
- package/src/serialize/markup/content.js +74 -0
- package/src/serialize/markup/dialect.js +178 -0
- package/src/serialize/markup/htmlData.js +70 -0
- package/src/serialize/markup/namespaces.js +145 -0
- package/src/serialize/markup/prolog.js +91 -0
- package/src/serialize/markup/writer.js +183 -0
- package/src/serialize/methods/adaptive.js +131 -0
- package/src/serialize/methods/json.js +158 -0
- package/src/serialize/methods/text.js +43 -0
- package/src/serialize/output/buffer.js +48 -0
- package/src/serialize/output/encoding.js +146 -0
- package/src/serialize/output/expander.js +204 -0
- package/src/serialize/params/fromElement.js +141 -0
- package/src/serialize/params/fromMap.js +128 -0
- package/src/serialize/params/names.js +69 -0
- package/src/serialize/params/settings.js +153 -0
- package/src/serialize/params/values.js +163 -0
- package/src/serialize/sequence.js +111 -0
- package/src/xdm/arithmetic.js +155 -0
- package/src/xdm/atomic.js +142 -0
- package/src/xdm/binary.js +92 -0
- package/src/xdm/calendar.js +71 -0
- package/src/xdm/cast.js +176 -0
- package/src/xdm/compare.js +192 -0
- package/src/xdm/datetime.js +206 -0
- package/src/xdm/decimal.js +200 -0
- package/src/xdm/duration.js +128 -0
- package/src/xdm/generalCompare.js +152 -0
- package/src/xdm/index.js +47 -0
- package/src/xdm/lexical.js +126 -0
- package/src/xdm/nodes.js +170 -0
- package/src/xdm/numeric.js +122 -0
- package/src/xdm/qname.js +65 -0
- package/src/xdm/strings.js +52 -0
- package/src/xdm/temporalArithmetic.js +180 -0
- package/src/xdm/timeline.js +68 -0
- package/src/xdm/types.js +178 -0
- package/src/xpath/eval/atomics.js +45 -0
- package/src/xpath/eval/axes.js +212 -0
- package/src/xpath/eval/calls.js +168 -0
- package/src/xpath/eval/coercion.js +146 -0
- package/src/xpath/eval/compiler.js +71 -0
- package/src/xpath/eval/constructors.js +129 -0
- package/src/xpath/eval/decimalFormats.js +93 -0
- package/src/xpath/eval/descendantMemo.js +77 -0
- package/src/xpath/eval/documentOrder.js +142 -0
- package/src/xpath/eval/domNodes.js +174 -0
- package/src/xpath/eval/dynamicCall.js +27 -0
- package/src/xpath/eval/dynamicContext.js +161 -0
- package/src/xpath/eval/flow.js +115 -0
- package/src/xpath/eval/functionItems.js +194 -0
- package/src/xpath/eval/groupedChildren.js +88 -0
- package/src/xpath/eval/inline.js +71 -0
- package/src/xpath/eval/namespaceNodes.js +90 -0
- package/src/xpath/eval/nodeTests.js +164 -0
- package/src/xpath/eval/operators.js +190 -0
- package/src/xpath/eval/paths.js +163 -0
- package/src/xpath/eval/positional.js +81 -0
- package/src/xpath/eval/predicates.js +56 -0
- package/src/xpath/eval/primary.js +99 -0
- package/src/xpath/eval/resources.js +149 -0
- package/src/xpath/eval/scope.js +108 -0
- package/src/xpath/eval/sequenceType.js +193 -0
- package/src/xpath/eval/staticContext.js +142 -0
- package/src/xpath/eval/steps.js +98 -0
- package/src/xpath/eval/subtype.js +154 -0
- package/src/xpath/eval/typeExprs.js +147 -0
- package/src/xpath/eval/typeNames.js +101 -0
- package/src/xpath/eval/uris.js +21 -0
- package/src/xpath/eval/values.js +64 -0
- package/src/xpath/index.js +217 -0
- package/src/xpath/syntax/ast.js +130 -0
- package/src/xpath/syntax/chars.js +58 -0
- package/src/xpath/syntax/constructors.js +144 -0
- package/src/xpath/syntax/expressions.js +107 -0
- package/src/xpath/syntax/index.js +44 -0
- package/src/xpath/syntax/kindTests.js +134 -0
- package/src/xpath/syntax/lexer.js +220 -0
- package/src/xpath/syntax/operators.js +111 -0
- package/src/xpath/syntax/paths.js +102 -0
- package/src/xpath/syntax/postfix.js +91 -0
- package/src/xpath/syntax/primaries.js +149 -0
- package/src/xpath/syntax/steps.js +146 -0
- package/src/xpath/syntax/syntaxError.js +31 -0
- package/src/xpath/syntax/tokenStream.js +163 -0
- package/src/xpath/syntax/typeAst.js +76 -0
- package/src/xpath/syntax/typeOperators.js +127 -0
- package/src/xpath/syntax/types.js +158 -0
- package/src/xslt/api.js +153 -0
- package/src/xslt/compiler/acceptance.js +178 -0
- package/src/xslt/compiler/accumulatorDecl.js +146 -0
- package/src/xslt/compiler/attributeValues.js +174 -0
- package/src/xslt/compiler/attributes.js +211 -0
- package/src/xslt/compiler/avt.js +103 -0
- package/src/xslt/compiler/body.js +154 -0
- package/src/xslt/compiler/children.js +105 -0
- package/src/xslt/compiler/compatibility.js +130 -0
- package/src/xslt/compiler/components.js +179 -0
- package/src/xslt/compiler/contextItem.js +95 -0
- package/src/xslt/compiler/decimalFormats.js +132 -0
- package/src/xslt/compiler/declarationKinds.js +82 -0
- package/src/xslt/compiler/elementInfo.js +246 -0
- package/src/xslt/compiler/expressions.js +175 -0
- package/src/xslt/compiler/globalContextItem.js +92 -0
- package/src/xslt/compiler/globals.js +209 -0
- package/src/xslt/compiler/linker.js +134 -0
- package/src/xslt/compiler/miscDecl.js +171 -0
- package/src/xslt/compiler/modeDecl.js +88 -0
- package/src/xslt/compiler/moduleLoading.js +111 -0
- package/src/xslt/compiler/modules.js +158 -0
- package/src/xslt/compiler/outputDecl.js +209 -0
- package/src/xslt/compiler/overrideLinks.js +141 -0
- package/src/xslt/compiler/packageChecks.js +84 -0
- package/src/xslt/compiler/packageRegistry.js +95 -0
- package/src/xslt/compiler/packageTable.js +181 -0
- package/src/xslt/compiler/packageVersions.js +143 -0
- package/src/xslt/compiler/packages.js +138 -0
- package/src/xslt/compiler/registry.js +234 -0
- package/src/xslt/compiler/staticStage.js +197 -0
- package/src/xslt/compiler/staticVariables.js +93 -0
- package/src/xslt/compiler/stylesheet.js +205 -0
- package/src/xslt/compiler/tailPosition.js +74 -0
- package/src/xslt/compiler/templatesDecl.js +180 -0
- package/src/xslt/compiler/useAccumulators.js +76 -0
- package/src/xslt/compiler/useWhen.js +94 -0
- package/src/xslt/compiler/visibility.js +160 -0
- package/src/xslt/index.js +11 -0
- package/src/xslt/instructions/analyzeString.js +137 -0
- package/src/xslt/instructions/assert.js +72 -0
- package/src/xslt/instructions/attributeSets.js +115 -0
- package/src/xslt/instructions/conditional.js +99 -0
- package/src/xslt/instructions/control.js +123 -0
- package/src/xslt/instructions/copy.js +151 -0
- package/src/xslt/instructions/elements.js +161 -0
- package/src/xslt/instructions/evaluate.js +189 -0
- package/src/xslt/instructions/fork.js +35 -0
- package/src/xslt/instructions/grouping.js +106 -0
- package/src/xslt/instructions/index.js +94 -0
- package/src/xslt/instructions/iterate.js +182 -0
- package/src/xslt/instructions/literal.js +142 -0
- package/src/xslt/instructions/maps.js +72 -0
- package/src/xslt/instructions/merge.js +190 -0
- package/src/xslt/instructions/number.js +205 -0
- package/src/xslt/instructions/output.js +102 -0
- package/src/xslt/instructions/params.js +110 -0
- package/src/xslt/instructions/resultDocument.js +143 -0
- package/src/xslt/instructions/sort.js +114 -0
- package/src/xslt/instructions/sourceDocument.js +73 -0
- package/src/xslt/instructions/templates.js +153 -0
- package/src/xslt/instructions/text.js +151 -0
- package/src/xslt/instructions/try.js +186 -0
- package/src/xslt/instructions/variables.js +119 -0
- package/src/xslt/names.js +204 -0
- package/src/xslt/patterns/axisOrigins.js +121 -0
- package/src/xslt/patterns/compile.js +151 -0
- package/src/xslt/patterns/general.js +132 -0
- package/src/xslt/patterns/grammar.js +190 -0
- package/src/xslt/patterns/modes.js +153 -0
- package/src/xslt/patterns/paths.js +130 -0
- package/src/xslt/patterns/patternChecks.js +29 -0
- package/src/xslt/patterns/steps.js +162 -0
- package/src/xslt/processor.js +178 -0
- package/src/xslt/runtime/accumulatorFunctions.js +48 -0
- package/src/xslt/runtime/accumulators.js +174 -0
- package/src/xslt/runtime/apply.js +153 -0
- package/src/xslt/runtime/atomicKeys.js +36 -0
- package/src/xslt/runtime/availability.js +162 -0
- package/src/xslt/runtime/baseUri.js +64 -0
- package/src/xslt/runtime/compilerHook.js +27 -0
- package/src/xslt/runtime/conditional.js +110 -0
- package/src/xslt/runtime/context.js +106 -0
- package/src/xslt/runtime/copy.js +123 -0
- package/src/xslt/runtime/copyFunctions.js +71 -0
- package/src/xslt/runtime/copyOrigins.js +60 -0
- package/src/xslt/runtime/defaultMethod.js +42 -0
- package/src/xslt/runtime/documentContent.js +93 -0
- package/src/xslt/runtime/dynamicXPath.js +90 -0
- package/src/xslt/runtime/functionCache.js +65 -0
- package/src/xslt/runtime/functionCall.js +57 -0
- package/src/xslt/runtime/functions.js +191 -0
- package/src/xslt/runtime/groups.js +108 -0
- package/src/xslt/runtime/invocation.js +156 -0
- package/src/xslt/runtime/iteration.js +107 -0
- package/src/xslt/runtime/keys.js +141 -0
- package/src/xslt/runtime/lazy.js +97 -0
- package/src/xslt/runtime/locations.js +86 -0
- package/src/xslt/runtime/machine.js +137 -0
- package/src/xslt/runtime/merging.js +167 -0
- package/src/xslt/runtime/namespaceScope.js +141 -0
- package/src/xslt/runtime/numberFormat.js +89 -0
- package/src/xslt/runtime/numbering.js +168 -0
- package/src/xslt/runtime/params.js +59 -0
- package/src/xslt/runtime/properties.js +103 -0
- package/src/xslt/runtime/rawResults.js +82 -0
- package/src/xslt/runtime/sequenceReceiver.js +102 -0
- package/src/xslt/runtime/snapshot.js +66 -0
- package/src/xslt/runtime/sortKeys.js +119 -0
- package/src/xslt/runtime/streamAvailable.js +60 -0
- package/src/xslt/runtime/strip.js +102 -0
- package/src/xslt/runtime/transformFunction.js +169 -0
- package/src/xslt/runtime/transformation.js +168 -0
- package/src/xslt/runtime/transformationContext.js +85 -0
- package/src/xslt/runtime/treeReceiver.js +194 -0
- package/src/xslt/runtime/values.js +92 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser of the XPath 3.1 expressions between the binary operators and the
|
|
3
|
+
* paths: productions [25] InstanceofExpr to [35] SimpleMapExpr of Appendix
|
|
4
|
+
* A.1 (instance of, treat as, castable as, cast as, `=>`, unary signs and
|
|
5
|
+
* `!`).
|
|
6
|
+
*
|
|
7
|
+
* @module @tradik/xslt3/xpath/syntax/typeOperators
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { makeNode } from "./ast.js";
|
|
11
|
+
import { parsePathExpr } from "./paths.js";
|
|
12
|
+
import { parseArgumentList } from "./postfix.js";
|
|
13
|
+
import { parseParenthesizedExpr, parseVarRef } from "./primaries.js";
|
|
14
|
+
import { qName } from "./tokenStream.js";
|
|
15
|
+
import { parseSequenceType, parseSingleType } from "./types.js";
|
|
16
|
+
|
|
17
|
+
/** @typedef {import("./tokenStream.js").TokenStream} TokenStream */
|
|
18
|
+
/** @typedef {import("./ast.js").Expr} Expr */
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* SimpleMapExpr ::= PathExpr ("!" PathExpr)*
|
|
22
|
+
*
|
|
23
|
+
* @param {TokenStream} p - Tokens
|
|
24
|
+
* @returns {Expr} The node
|
|
25
|
+
*/
|
|
26
|
+
function parseSimpleMapExpr(p) {
|
|
27
|
+
let left = parsePathExpr(p);
|
|
28
|
+
while (p.acceptSymbol("!")) {
|
|
29
|
+
const right = parsePathExpr(p);
|
|
30
|
+
left = makeNode("SimpleMapExpr", { left, right }, left.start, right.end);
|
|
31
|
+
}
|
|
32
|
+
return left;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* UnaryExpr ::= ("-" | "+")* ValueExpr, ValueExpr being a SimpleMapExpr.
|
|
37
|
+
*
|
|
38
|
+
* @param {TokenStream} p - Tokens
|
|
39
|
+
* @returns {Expr} The node
|
|
40
|
+
*/
|
|
41
|
+
function parseUnaryExpr(p) {
|
|
42
|
+
const sign = p.acceptSymbol("-") ?? p.acceptSymbol("+");
|
|
43
|
+
if (!sign) return parseSimpleMapExpr(p);
|
|
44
|
+
const operand = parseUnaryExpr(p);
|
|
45
|
+
const fields = { operator: sign.value, operand };
|
|
46
|
+
return makeNode("UnaryExpr", fields, sign.start, operand.end);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* ArrowExpr ::= UnaryExpr ("=>" ArrowFunctionSpecifier ArgumentList)*,
|
|
51
|
+
* the specifier being an EQName, a VarRef or a ParenthesizedExpr.
|
|
52
|
+
*
|
|
53
|
+
* @param {TokenStream} p - Tokens
|
|
54
|
+
* @returns {Expr} The node
|
|
55
|
+
*/
|
|
56
|
+
function parseArrowExpr(p) {
|
|
57
|
+
let expr = parseUnaryExpr(p);
|
|
58
|
+
while (p.acceptSymbol("=>")) {
|
|
59
|
+
let functionName = null;
|
|
60
|
+
let functionExpr = null;
|
|
61
|
+
if (p.peek().type === "name") functionName = qName(p.next());
|
|
62
|
+
else if (p.isSymbol("$")) functionExpr = parseVarRef(p);
|
|
63
|
+
else if (p.isSymbol("(")) functionExpr = parseParenthesizedExpr(p);
|
|
64
|
+
else p.fail('Expected a function after "=>"');
|
|
65
|
+
const { arguments: args, end } = parseArgumentList(p);
|
|
66
|
+
const fields = { expr, functionName, functionExpr, arguments: args };
|
|
67
|
+
expr = makeNode("ArrowExpr", fields, expr.start, end);
|
|
68
|
+
}
|
|
69
|
+
return expr;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Builds the parser of `E keyword1 keyword2 Type` (instance of, treat as,
|
|
74
|
+
* castable as, cast as). Each operator may appear at most once.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} type - Node type
|
|
77
|
+
* @param {string} keywords - The two keywords, space-separated
|
|
78
|
+
* @param {(p: TokenStream) => Expr} operand - Parser of the next level
|
|
79
|
+
* @param {boolean} single - SingleType (cast, castable) or SequenceType
|
|
80
|
+
* @returns {(p: TokenStream) => Expr} Parser of the level
|
|
81
|
+
*/
|
|
82
|
+
function typeLevel(type, keywords, operand, single) {
|
|
83
|
+
const [first, second] = keywords.split(" ");
|
|
84
|
+
return (p) => {
|
|
85
|
+
const expr = operand(p);
|
|
86
|
+
if (!p.acceptKeyword(first)) return expr;
|
|
87
|
+
p.expectKeyword(second);
|
|
88
|
+
if (single) {
|
|
89
|
+
const { name, emptyAllowed, end } = parseSingleType(p);
|
|
90
|
+
const fields = { expr, targetType: name, emptyAllowed };
|
|
91
|
+
return makeNode(type, fields, expr.start, end);
|
|
92
|
+
}
|
|
93
|
+
const sequenceType = parseSequenceType(p);
|
|
94
|
+
return makeNode(type, { expr, sequenceType }, expr.start, sequenceType.end);
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const parseCastExpr = typeLevel("CastExpr", "cast as", parseArrowExpr, true);
|
|
99
|
+
const parseCastableExpr = typeLevel(
|
|
100
|
+
"CastableExpr",
|
|
101
|
+
"castable as",
|
|
102
|
+
parseCastExpr,
|
|
103
|
+
true,
|
|
104
|
+
);
|
|
105
|
+
const parseTreatExpr = typeLevel(
|
|
106
|
+
"TreatExpr",
|
|
107
|
+
"treat as",
|
|
108
|
+
parseCastableExpr,
|
|
109
|
+
false,
|
|
110
|
+
);
|
|
111
|
+
const parseInstanceof = typeLevel(
|
|
112
|
+
"InstanceOfExpr",
|
|
113
|
+
"instance of",
|
|
114
|
+
parseTreatExpr,
|
|
115
|
+
false,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* InstanceofExpr ::= TreatExpr ("instance" "of" SequenceType)?, the entry
|
|
120
|
+
* point of this module.
|
|
121
|
+
*
|
|
122
|
+
* @param {TokenStream} p - Tokens
|
|
123
|
+
* @returns {Expr} The node
|
|
124
|
+
*/
|
|
125
|
+
export function parseInstanceofExpr(p) {
|
|
126
|
+
return parseInstanceof(p);
|
|
127
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser of XPath 3.1 types: SingleType, SequenceType and ItemType with the
|
|
3
|
+
* function, map and array tests (productions [77] SingleType to [116]
|
|
4
|
+
* ParenthesizedItemType of Appendix A.1). Kind tests are in kindTests.js.
|
|
5
|
+
*
|
|
6
|
+
* Occurrence-indicators constraint (A.1.2): a `?`, `*` or `+` right after
|
|
7
|
+
* an item type always belongs to it, so `4 treat as item() + - 5` is
|
|
8
|
+
* `(4 treat as item()+) - 5`.
|
|
9
|
+
*
|
|
10
|
+
* @module @tradik/xslt3/xpath/syntax/types
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { makeNode } from "./ast.js";
|
|
14
|
+
import { isKindTestName, parseKindTest } from "./kindTests.js";
|
|
15
|
+
import { isPlainName, qName } from "./tokenStream.js";
|
|
16
|
+
|
|
17
|
+
/** @typedef {import("./tokenStream.js").TokenStream} TokenStream */
|
|
18
|
+
/** @typedef {import("./typeAst.js").SequenceType} SequenceType */
|
|
19
|
+
/** @typedef {import("./typeAst.js").ItemType} ItemType */
|
|
20
|
+
|
|
21
|
+
const OCCURRENCES = ["?", "*", "+"];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* SingleType ::= SimpleTypeName "?"?
|
|
25
|
+
*
|
|
26
|
+
* @param {TokenStream} p - Tokens
|
|
27
|
+
* @returns {{name: import("./ast.js").QName, emptyAllowed: boolean, end: number}}
|
|
28
|
+
* The type name, whether "?" follows, and the offset after the type
|
|
29
|
+
*/
|
|
30
|
+
export function parseSingleType(p) {
|
|
31
|
+
const token = p.expectName("a type name");
|
|
32
|
+
const question = p.acceptSymbol("?");
|
|
33
|
+
const end = question ? question.end : token.end;
|
|
34
|
+
return { name: qName(token), emptyAllowed: Boolean(question), end };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* SequenceType ::= ("empty-sequence" "(" ")") | (ItemType OccurrenceIndicator?)
|
|
39
|
+
*
|
|
40
|
+
* @param {TokenStream} p - Tokens
|
|
41
|
+
* @returns {SequenceType} The type
|
|
42
|
+
*/
|
|
43
|
+
export function parseSequenceType(p) {
|
|
44
|
+
const start = p.peek().start;
|
|
45
|
+
if (p.isKeyword("empty-sequence") && p.isSymbol("(", 1)) {
|
|
46
|
+
p.next();
|
|
47
|
+
p.next();
|
|
48
|
+
const end = p.expectSymbol(")").end;
|
|
49
|
+
return makeNode(
|
|
50
|
+
"SequenceType",
|
|
51
|
+
{ itemType: null, occurrence: "" },
|
|
52
|
+
start,
|
|
53
|
+
end,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
const itemType = parseItemType(p);
|
|
57
|
+
const indicator = OCCURRENCES.find((symbol) => p.isSymbol(symbol));
|
|
58
|
+
const end = indicator ? p.next().end : itemType.end;
|
|
59
|
+
return makeNode(
|
|
60
|
+
"SequenceType",
|
|
61
|
+
{ itemType, occurrence: indicator ?? "" },
|
|
62
|
+
start,
|
|
63
|
+
end,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* ItemType ::= KindTest | ("item" "(" ")") | FunctionTest | MapTest |
|
|
69
|
+
* ArrayTest | AtomicOrUnionType | ParenthesizedItemType
|
|
70
|
+
*
|
|
71
|
+
* @param {TokenStream} p - Tokens
|
|
72
|
+
* @returns {ItemType} The type
|
|
73
|
+
*/
|
|
74
|
+
export function parseItemType(p) {
|
|
75
|
+
const token = p.peek();
|
|
76
|
+
if (p.acceptSymbol("(")) {
|
|
77
|
+
const inner = parseItemType(p);
|
|
78
|
+
p.expectSymbol(")");
|
|
79
|
+
return inner;
|
|
80
|
+
}
|
|
81
|
+
if (token.type !== "name") p.fail("Expected an item type");
|
|
82
|
+
if (p.isSymbol("(", 1)) {
|
|
83
|
+
if (isKindTestName(token)) return parseKindTest(p);
|
|
84
|
+
const parse =
|
|
85
|
+
isPlainName(token) && Object.hasOwn(TYPE_TESTS, token.local)
|
|
86
|
+
? TYPE_TESTS[token.local]
|
|
87
|
+
: null;
|
|
88
|
+
if (parse) {
|
|
89
|
+
p.next();
|
|
90
|
+
p.next();
|
|
91
|
+
const { type, ...fields } = parse(p);
|
|
92
|
+
let end = p.expectSymbol(")").end;
|
|
93
|
+
if (type === "TypedFunctionTest") {
|
|
94
|
+
p.expectKeyword("as");
|
|
95
|
+
fields.returnType = parseSequenceType(p);
|
|
96
|
+
end = fields.returnType.end;
|
|
97
|
+
}
|
|
98
|
+
return makeNode(type, fields, token.start, end);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
p.next();
|
|
102
|
+
return makeNode("AtomicType", { name: qName(token) }, token.start, token.end);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Parsers of the item tests with a keyword, after the "(". */
|
|
106
|
+
const TYPE_TESTS = {
|
|
107
|
+
item: () => ({ type: "AnyItemTest" }),
|
|
108
|
+
function: parseFunctionTestBody,
|
|
109
|
+
map: parseMapTestBody,
|
|
110
|
+
array: parseArrayTestBody,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Inside `function(...)`: "*" or the parameter types; the caller reads the
|
|
115
|
+
* `as` return type of a typed test after the ")".
|
|
116
|
+
*
|
|
117
|
+
* @param {TokenStream} p - Tokens
|
|
118
|
+
* @returns {object} Fields of the test
|
|
119
|
+
*/
|
|
120
|
+
function parseFunctionTestBody(p) {
|
|
121
|
+
if (p.acceptSymbol("*")) return { type: "AnyFunctionTest" };
|
|
122
|
+
const paramTypes = [];
|
|
123
|
+
if (!p.isSymbol(")")) {
|
|
124
|
+
do paramTypes.push(parseSequenceType(p));
|
|
125
|
+
while (p.acceptSymbol(","));
|
|
126
|
+
}
|
|
127
|
+
return { type: "TypedFunctionTest", paramTypes };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Inside `map(...)`: "*" or AtomicOrUnionType "," SequenceType.
|
|
132
|
+
*
|
|
133
|
+
* @param {TokenStream} p - Tokens
|
|
134
|
+
* @returns {object} Fields of the test
|
|
135
|
+
*/
|
|
136
|
+
function parseMapTestBody(p) {
|
|
137
|
+
if (p.acceptSymbol("*")) return { type: "AnyMapTest" };
|
|
138
|
+
const token = p.expectName("an atomic type");
|
|
139
|
+
const keyType = makeNode(
|
|
140
|
+
"AtomicType",
|
|
141
|
+
{ name: qName(token) },
|
|
142
|
+
token.start,
|
|
143
|
+
token.end,
|
|
144
|
+
);
|
|
145
|
+
p.expectSymbol(",");
|
|
146
|
+
return { type: "TypedMapTest", keyType, valueType: parseSequenceType(p) };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Inside `array(...)`: "*" or SequenceType.
|
|
151
|
+
*
|
|
152
|
+
* @param {TokenStream} p - Tokens
|
|
153
|
+
* @returns {object} Fields of the test
|
|
154
|
+
*/
|
|
155
|
+
function parseArrayTestBody(p) {
|
|
156
|
+
if (p.acceptSymbol("*")) return { type: "AnyArrayTest" };
|
|
157
|
+
return { type: "TypedArrayTest", memberType: parseSequenceType(p) };
|
|
158
|
+
}
|
package/src/xslt/api.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XSLT 3.0 and 2.0 (and 1.0 in backwards-compatible mode): compile a
|
|
3
|
+
* stylesheet once, run it on many documents.
|
|
4
|
+
*
|
|
5
|
+
* ```js
|
|
6
|
+
* import { compileStylesheet } from "@tradik/xslt3";
|
|
7
|
+
* const stylesheet = compileStylesheet(xslDocument, { baseUri });
|
|
8
|
+
* const { principal, secondary, messages } = stylesheet.transform({
|
|
9
|
+
* source: xmlDocument,
|
|
10
|
+
* params: { title: "Report" },
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @module @tradik/xslt3/xslt
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { StylesheetCompiler } from "./compiler/stylesheet.js";
|
|
18
|
+
import { normalizeParams } from "./runtime/params.js";
|
|
19
|
+
import { withDefaultMethod } from "./runtime/defaultMethod.js";
|
|
20
|
+
import { setCompiler } from "./runtime/compilerHook.js";
|
|
21
|
+
import { runTransformation } from "./runtime/transformation.js";
|
|
22
|
+
import { xsltError } from "./names.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Parses XML text with the given parser or the global DOMParser.
|
|
26
|
+
* @param {string} text
|
|
27
|
+
* @param {string|undefined} uri
|
|
28
|
+
* @param {((text: string, uri?: string) => Document)|undefined} parseXml
|
|
29
|
+
* @returns {Document}
|
|
30
|
+
*/
|
|
31
|
+
function parse(text, uri, parseXml) {
|
|
32
|
+
if (parseXml) return parseXml(text, uri);
|
|
33
|
+
const Parser = globalThis.DOMParser;
|
|
34
|
+
if (!Parser) {
|
|
35
|
+
throw xsltError("XTSE0165", "No XML parser: pass the parseXml option");
|
|
36
|
+
}
|
|
37
|
+
return new Parser().parseFromString(text, "application/xml");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** A compiled stylesheet. */
|
|
41
|
+
export class CompiledStylesheet {
|
|
42
|
+
/** @param {StylesheetCompiler} compiled */
|
|
43
|
+
constructor(compiled) {
|
|
44
|
+
this.compiled = compiled;
|
|
45
|
+
/** @type {Map<string, object>} xsl:output parameters by Clark name ("" unnamed) */
|
|
46
|
+
this.outputs = compiled.outputs;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The parameters of the unnamed output definition, with
|
|
51
|
+
* `use-character-maps` expanded to a Map of characters to strings.
|
|
52
|
+
* @returns {object}
|
|
53
|
+
*/
|
|
54
|
+
get output() {
|
|
55
|
+
return this.compiled.outputFor(null);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Runs the stylesheet.
|
|
60
|
+
* @param {object} [options]
|
|
61
|
+
* @param {Node} [options.source] - Source document (global context item
|
|
62
|
+
* and initial match selection)
|
|
63
|
+
* @param {string} [options.initialTemplate] - Name of the initial
|
|
64
|
+
* template (`local`, `Q{uri}local`)
|
|
65
|
+
* @param {string} [options.initialMode] - Clark name of the initial mode
|
|
66
|
+
* @param {Array} [options.initialMatchSelection] - Items to apply
|
|
67
|
+
* templates to (default: the source)
|
|
68
|
+
* @param {object|Map} [options.params] - Stylesheet parameters by name
|
|
69
|
+
* @param {boolean} [options.paramsAsUntyped] - JavaScript strings among
|
|
70
|
+
* the stylesheet parameters are xs:untypedAtomic, so that they convert
|
|
71
|
+
* to the declared type (`as="xs:integer"`) as command-line parameters
|
|
72
|
+
* do in other processors; see also `untypedAtomic()`
|
|
73
|
+
* @param {object|Map} [options.templateParams] - Parameters of the
|
|
74
|
+
* initial template or mode
|
|
75
|
+
* @param {object|Map} [options.tunnelParams] - Tunnel parameters
|
|
76
|
+
* @param {(uri: string, base?: string) => Document} [options.documentLoader]
|
|
77
|
+
* - Loads documents for doc() and document(): gets the absolute URI
|
|
78
|
+
* and the base URI the reference was resolved against
|
|
79
|
+
* @param {(uri: string) => (string|Uint8Array|object|null)} [options.textLoader]
|
|
80
|
+
* - Reads text resources for unparsed-text(), json-doc() and the like
|
|
81
|
+
* (default: none; `readFileUri` reads `file:` URIs)
|
|
82
|
+
* @param {(uri: string|null) => Array|null} [options.collections] - The
|
|
83
|
+
* items of a collection for collection() and uri-collection(), `uri`
|
|
84
|
+
* null for the default collection (default: none)
|
|
85
|
+
* @param {(text: string, baseUri?: string) => Document} [options.xmlParser]
|
|
86
|
+
* - Parser for parse-xml() (default: the global DOMParser)
|
|
87
|
+
* @param {() => Document} [options.createDocument] - Creates documents
|
|
88
|
+
* @param {(message: Node) => void} [options.onMessage] - xsl:message
|
|
89
|
+
* @param {string} [options.baseOutputUri] - Base of result-document URIs
|
|
90
|
+
* @param {{name: string, args: Array}} [options.initialFunction] - A
|
|
91
|
+
* stylesheet function to call instead (its result is the principal
|
|
92
|
+
* result)
|
|
93
|
+
* @param {*} [options.globalContextItem] - Default: the source
|
|
94
|
+
* @param {number} [options.implicitTimezone] - Minutes, default 0
|
|
95
|
+
* @param {Date} [options.currentDateTime] - Default: now
|
|
96
|
+
* @param {boolean} [options.buildTree] - Overrides the build-tree
|
|
97
|
+
* serialization parameter of every result: false delivers the raw
|
|
98
|
+
* sequences (as fn:transform does for delivery-format "raw")
|
|
99
|
+
* @param {number} [options.maxDepth] - Deepest nesting of instructions
|
|
100
|
+
* (default 1,000,000; deeper is reported as an infinite recursion)
|
|
101
|
+
* @returns {{principal: Node|Array, secondary: Map<string, {document:
|
|
102
|
+
* Node, output: object}>, messages: Array, output: object}} the
|
|
103
|
+
* results; `output` holds the serialization parameters of the
|
|
104
|
+
* principal result: those of the xsl:result-document that wrote it,
|
|
105
|
+
* else those of the `output` getter
|
|
106
|
+
*/
|
|
107
|
+
transform(options = {}) {
|
|
108
|
+
const { principalOutput, ...result } = runTransformation(
|
|
109
|
+
this.compiled,
|
|
110
|
+
options,
|
|
111
|
+
);
|
|
112
|
+
const output =
|
|
113
|
+
principalOutput ??
|
|
114
|
+
withDefaultMethod(
|
|
115
|
+
this.output,
|
|
116
|
+
result.principal,
|
|
117
|
+
this.compiled.versionOf(this.compiled.tree.root) === 1,
|
|
118
|
+
);
|
|
119
|
+
return { ...result, output };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Compiles a stylesheet.
|
|
125
|
+
* @param {Document|Element|string} stylesheet - The principal module
|
|
126
|
+
* @param {object} [options]
|
|
127
|
+
* @param {string} [options.baseUri] - URI of the principal module
|
|
128
|
+
* @param {(uri: string, base?: string) => Document|string} [options.loadStylesheet]
|
|
129
|
+
* - Loads included and imported modules (and parameter documents): gets
|
|
130
|
+
* the absolute URI and the base URI the href was resolved against
|
|
131
|
+
* @param {(text: string, uri?: string) => Document} [options.parseXml] -
|
|
132
|
+
* XML parser (default: the global DOMParser)
|
|
133
|
+
* @param {object|Map} [options.staticParams] - Values of static
|
|
134
|
+
* parameters (XSLT 3.0) by name
|
|
135
|
+
* @returns {CompiledStylesheet}
|
|
136
|
+
* @throws {import("../errors.js").XPathError} the static errors (XTSE...)
|
|
137
|
+
*/
|
|
138
|
+
export function compileStylesheet(stylesheet, options = {}) {
|
|
139
|
+
const parseXml = (text, uri) => parse(text, uri, options.parseXml);
|
|
140
|
+
const source =
|
|
141
|
+
typeof stylesheet === "string"
|
|
142
|
+
? parseXml(stylesheet, options.baseUri)
|
|
143
|
+
: stylesheet;
|
|
144
|
+
const compiler = new StylesheetCompiler({
|
|
145
|
+
...options,
|
|
146
|
+
parse: parseXml,
|
|
147
|
+
staticParams: normalizeParams(options.staticParams),
|
|
148
|
+
});
|
|
149
|
+
const uri = options.baseUri ?? (source.documentURI || undefined);
|
|
150
|
+
return new CompiledStylesheet(compiler.compile(source, uri));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
setCompiler(compileStylesheet);
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The components of a used package seen from the using package (XSLT 3.0
|
|
3
|
+
* sections 3.5.3.2 and 3.5.3.3): the overriding declarations matched to
|
|
4
|
+
* the components they override, and the visibility of every other
|
|
5
|
+
* component after xsl:accept.
|
|
6
|
+
*
|
|
7
|
+
* @module @tradik/xslt3/xslt/compiler/acceptance
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { attr, clarkOf, isXsl, tokens, xsltError } from "../names.js";
|
|
11
|
+
import { checkCompatible } from "./compatibility.js";
|
|
12
|
+
import { declaredVisibility } from "./components.js";
|
|
13
|
+
import { infoOf } from "./elementInfo.js";
|
|
14
|
+
import { splitParams } from "./templatesDecl.js";
|
|
15
|
+
import { EXPLICIT, matchesOf } from "./visibility.js";
|
|
16
|
+
|
|
17
|
+
/** Errors of two overriding declarations of the same component. */
|
|
18
|
+
const DUPLICATE = {
|
|
19
|
+
template: "XTSE0660",
|
|
20
|
+
function: "XTSE0770",
|
|
21
|
+
variable: "XTSE0630",
|
|
22
|
+
"attribute-set": "XTSE3055",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/** Visibilities in the used package that each xsl:accept value allows. */
|
|
26
|
+
const ACCEPTABLE = {
|
|
27
|
+
public: ["public"],
|
|
28
|
+
private: ["public", "final"],
|
|
29
|
+
final: ["public", "final"],
|
|
30
|
+
abstract: ["abstract"],
|
|
31
|
+
hidden: ["public", "final", "abstract"],
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The visibility in the using package of a component that is not
|
|
36
|
+
* overridden (Visibility of Components in Used and Using Packages).
|
|
37
|
+
* @param {object} component - Exported by the used package
|
|
38
|
+
* @param {object[]} rules - Parsed xsl:accept rules
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
function acceptedVisibility(component, rules) {
|
|
42
|
+
if (component.isParam) return "public";
|
|
43
|
+
for (const { rule, precision } of matchesOf(rules, component)) {
|
|
44
|
+
if (ACCEPTABLE[rule.visibility].includes(component.visibility)) {
|
|
45
|
+
return rule.visibility;
|
|
46
|
+
}
|
|
47
|
+
if (precision === EXPLICIT) {
|
|
48
|
+
throw xsltError(
|
|
49
|
+
"XTSE3040",
|
|
50
|
+
`${component.local} cannot be accepted as ${rule.visibility}`,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return ["public", "final"].includes(component.visibility)
|
|
55
|
+
? "private"
|
|
56
|
+
: "hidden";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The component an overriding declaration names.
|
|
61
|
+
* @param {Element} element - Child of xsl:override
|
|
62
|
+
* @param {object} cx
|
|
63
|
+
* @returns {object|null} `{kind, uri, local, arity, key}`, null for a
|
|
64
|
+
* template rule without a name
|
|
65
|
+
*/
|
|
66
|
+
function overrideSymbol(element, cx) {
|
|
67
|
+
const name = attr(element, "name");
|
|
68
|
+
if (name === undefined) return null;
|
|
69
|
+
const qname = cx.exprs.qname(name, element);
|
|
70
|
+
const kind = element.localName === "param" ? "variable" : element.localName;
|
|
71
|
+
const key = `{${qname.uri}}${qname.local}`;
|
|
72
|
+
if (kind !== "function") return { kind, ...qname, arity: null, key };
|
|
73
|
+
const arity = splitParams(cx.children(element)).params.length;
|
|
74
|
+
return { kind, ...qname, arity, key: `${key}#${arity}` };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Checks that the modes of an overriding template rule are public modes
|
|
79
|
+
* of the used package (XTSE3440 for the unnamed mode, XTSE3060).
|
|
80
|
+
* @param {Element} element - xsl:template with a match pattern
|
|
81
|
+
* @param {Map<string, object>} byKey - Exported components
|
|
82
|
+
* @param {object} cx
|
|
83
|
+
*/
|
|
84
|
+
function checkRuleModes(element, byKey, cx) {
|
|
85
|
+
const text = attr(element, "mode");
|
|
86
|
+
const { defaultMode } = infoOf(element);
|
|
87
|
+
const keys =
|
|
88
|
+
text === undefined
|
|
89
|
+
? [defaultMode]
|
|
90
|
+
: tokens(text).map((token) => {
|
|
91
|
+
if (token === "#default") return defaultMode;
|
|
92
|
+
return token.startsWith("#")
|
|
93
|
+
? ""
|
|
94
|
+
: clarkOf(cx.exprs.qname(token, element));
|
|
95
|
+
});
|
|
96
|
+
for (const key of keys) {
|
|
97
|
+
if (key === "") {
|
|
98
|
+
throw xsltError("XTSE3440", "An overriding template rule needs a mode");
|
|
99
|
+
}
|
|
100
|
+
if (byKey.get(`mode ${key}`)?.visibility !== "public") {
|
|
101
|
+
throw xsltError("XTSE3060", `No template rules can be added to ${key}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Matches the overriding declarations of an xsl:use-package with the
|
|
108
|
+
* components they override.
|
|
109
|
+
* @param {Element[]} overrides - Children of xsl:override
|
|
110
|
+
* @param {object[]} rules - Parsed xsl:accept rules
|
|
111
|
+
* @param {Map<string, object>} byKey - Exported components by "kind key"
|
|
112
|
+
* @param {object} cx - The using package's compiler
|
|
113
|
+
* @returns {{list: object[], overridden: Map<object, Element>}} the
|
|
114
|
+
* declarations `{element, symbol, component}` and the overridden
|
|
115
|
+
* components
|
|
116
|
+
*/
|
|
117
|
+
export function matchOverrides(overrides, rules, byKey, cx) {
|
|
118
|
+
const overridden = new Map();
|
|
119
|
+
const list = [];
|
|
120
|
+
for (const element of overrides) {
|
|
121
|
+
const symbol = overrideSymbol(element, cx);
|
|
122
|
+
if (attr(element, "match") !== undefined) {
|
|
123
|
+
checkRuleModes(element, byKey, cx);
|
|
124
|
+
}
|
|
125
|
+
if (!symbol) {
|
|
126
|
+
list.push({ element, symbol: null, component: null });
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const component = byKey.get(`${symbol.kind} ${symbol.key}`);
|
|
130
|
+
if (!component) {
|
|
131
|
+
throw xsltError("XTSE3058", `${symbol.local} overrides nothing`);
|
|
132
|
+
}
|
|
133
|
+
if (!["public", "abstract"].includes(component.visibility)) {
|
|
134
|
+
throw xsltError("XTSE3060", `${symbol.local} cannot be overridden`);
|
|
135
|
+
}
|
|
136
|
+
if (matchesOf(rules, symbol).some((m) => m.precision === EXPLICIT)) {
|
|
137
|
+
throw xsltError("XTSE3051", `${symbol.local} is accepted and overridden`);
|
|
138
|
+
}
|
|
139
|
+
if (overridden.has(component)) {
|
|
140
|
+
throw xsltError(DUPLICATE[symbol.kind], `${symbol.local} twice`);
|
|
141
|
+
}
|
|
142
|
+
checkCompatible(element, component, cx);
|
|
143
|
+
overridden.set(component, element);
|
|
144
|
+
list.push({ element, symbol, component });
|
|
145
|
+
}
|
|
146
|
+
return { list, overridden };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* The components of the used package with their visibility in the using
|
|
151
|
+
* package, hidden ones left out.
|
|
152
|
+
* @param {object[]} exported - Components exported by the used package
|
|
153
|
+
* @param {Map<object, Element>} overridden - From {@link matchOverrides}
|
|
154
|
+
* @param {object[]} rules - Parsed xsl:accept rules
|
|
155
|
+
* @param {boolean} [implicit] - The using package is an implicit one (an
|
|
156
|
+
* xsl:stylesheet), whose templates and modes are public by default
|
|
157
|
+
* @returns {object[]} `{component, visibility, override}`
|
|
158
|
+
*/
|
|
159
|
+
export function acceptComponents(exported, overridden, rules, implicit) {
|
|
160
|
+
const accepted = [];
|
|
161
|
+
for (const component of exported) {
|
|
162
|
+
const element = overridden.get(component);
|
|
163
|
+
let visibility;
|
|
164
|
+
if (!element) visibility = acceptedVisibility(component, rules);
|
|
165
|
+
else if (isXsl(element, "param")) visibility = "public";
|
|
166
|
+
else {
|
|
167
|
+
const fallback =
|
|
168
|
+
implicit && ["template", "mode"].includes(component.kind)
|
|
169
|
+
? "public"
|
|
170
|
+
: "private";
|
|
171
|
+
visibility = declaredVisibility(element, component.kind) ?? fallback;
|
|
172
|
+
}
|
|
173
|
+
if (visibility !== "hidden") {
|
|
174
|
+
accepted.push({ component, visibility, override: element ?? null });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return accepted;
|
|
178
|
+
}
|