@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,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser of XPath 3.1 postfix expressions: productions [49] PostfixExpr,
|
|
3
|
+
* [50] ArgumentList, [53] Lookup and [54] KeySpecifier of Appendix A.1
|
|
4
|
+
* (predicates, dynamic function calls and lookups after a primary).
|
|
5
|
+
*
|
|
6
|
+
* @module @tradik/xslt3/xpath/syntax/postfix
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { makeNode } from "./ast.js";
|
|
10
|
+
import { parseExprSingle } from "./expressions.js";
|
|
11
|
+
import { parseParenthesizedExpr, parsePrimaryExpr } from "./primaries.js";
|
|
12
|
+
import { parsePredicate } from "./steps.js";
|
|
13
|
+
import { isPlainName } from "./tokenStream.js";
|
|
14
|
+
|
|
15
|
+
/** @typedef {import("./tokenStream.js").TokenStream} TokenStream */
|
|
16
|
+
/** @typedef {import("./ast.js").Expr} Expr */
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* PostfixExpr ::= PrimaryExpr (Predicate | ArgumentList | Lookup)*
|
|
20
|
+
*
|
|
21
|
+
* @param {TokenStream} p - Tokens
|
|
22
|
+
* @returns {Expr} The expression
|
|
23
|
+
*/
|
|
24
|
+
export function parsePostfixExpr(p) {
|
|
25
|
+
let expr = parsePrimaryExpr(p);
|
|
26
|
+
for (;;) {
|
|
27
|
+
if (p.isSymbol("[")) {
|
|
28
|
+
const { predicate, end } = parsePredicate(p);
|
|
29
|
+
expr = makeNode("FilterExpr", { base: expr, predicate }, expr.start, end);
|
|
30
|
+
} else if (p.isSymbol("(")) {
|
|
31
|
+
const { arguments: args, end } = parseArgumentList(p);
|
|
32
|
+
expr = makeNode(
|
|
33
|
+
"DynamicFunctionCall",
|
|
34
|
+
{ functionExpr: expr, arguments: args },
|
|
35
|
+
expr.start,
|
|
36
|
+
end,
|
|
37
|
+
);
|
|
38
|
+
} else if (p.acceptSymbol("?")) {
|
|
39
|
+
const { keyKind, key, end } = parseKeySpecifier(p);
|
|
40
|
+
expr = makeNode("Lookup", { base: expr, keyKind, key }, expr.start, end);
|
|
41
|
+
} else {
|
|
42
|
+
return expr;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* ArgumentList ::= "(" (Argument ("," Argument)*)? ")", an Argument being
|
|
49
|
+
* an ExprSingle or the placeholder "?" (partial function application).
|
|
50
|
+
*
|
|
51
|
+
* @param {TokenStream} p - Tokens, at "("
|
|
52
|
+
* @returns {{arguments: Array<Expr|import("./ast.js").ArgumentPlaceholder>, end: number}}
|
|
53
|
+
* The arguments and the offset after ")"
|
|
54
|
+
*/
|
|
55
|
+
export function parseArgumentList(p) {
|
|
56
|
+
p.expectSymbol("(");
|
|
57
|
+
const args = [];
|
|
58
|
+
if (!p.isSymbol(")")) {
|
|
59
|
+
do {
|
|
60
|
+
if (p.isSymbol("?") && (p.isSymbol(",", 1) || p.isSymbol(")", 1))) {
|
|
61
|
+
const { start, end } = p.next();
|
|
62
|
+
args.push(makeNode("ArgumentPlaceholder", {}, start, end));
|
|
63
|
+
} else {
|
|
64
|
+
args.push(parseExprSingle(p));
|
|
65
|
+
}
|
|
66
|
+
} while (p.acceptSymbol(","));
|
|
67
|
+
}
|
|
68
|
+
return { arguments: args, end: p.expectSymbol(")").end };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* KeySpecifier ::= NCName | IntegerLiteral | ParenthesizedExpr | "*", after
|
|
73
|
+
* the "?" of a lookup.
|
|
74
|
+
*
|
|
75
|
+
* @param {TokenStream} p - Tokens
|
|
76
|
+
* @returns {{keyKind: string, key: string|Expr|null, end: number}} The key
|
|
77
|
+
*/
|
|
78
|
+
export function parseKeySpecifier(p) {
|
|
79
|
+
const token = p.peek();
|
|
80
|
+
if (isPlainName(token) || token.type === "integer") {
|
|
81
|
+
p.next();
|
|
82
|
+
const keyKind = token.type === "name" ? "name" : "integer";
|
|
83
|
+
return { keyKind, key: token.local ?? token.value, end: token.end };
|
|
84
|
+
}
|
|
85
|
+
if (p.acceptSymbol("*")) {
|
|
86
|
+
return { keyKind: "wildcard", key: null, end: token.end };
|
|
87
|
+
}
|
|
88
|
+
if (!p.isSymbol("(")) p.fail('Expected a key: NCName, integer, "(" or "*"');
|
|
89
|
+
const key = parseParenthesizedExpr(p);
|
|
90
|
+
return { keyKind: "expr", key, end: p.lastEnd };
|
|
91
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser of XPath 3.1 primary expressions: productions [56] PrimaryExpr to
|
|
3
|
+
* [68] NamedFunctionRef and [76] UnaryLookup of Appendix A.1. Postfixes are
|
|
4
|
+
* in postfix.js; function, map and array constructors in constructors.js.
|
|
5
|
+
*
|
|
6
|
+
* Reserved-function-names constraint (A.3): an unprefixed name from
|
|
7
|
+
* {@link RESERVED_FUNCTION_NAMES} cannot be called or referenced as a
|
|
8
|
+
* function, so `if(1)` or `node#0` never are function calls.
|
|
9
|
+
*
|
|
10
|
+
* @module @tradik/xslt3/xpath/syntax/primaries
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { makeNode } from "./ast.js";
|
|
14
|
+
import {
|
|
15
|
+
parseCurlyArrayConstructor,
|
|
16
|
+
parseInlineFunctionExpr,
|
|
17
|
+
parseMapConstructor,
|
|
18
|
+
parseSquareArrayConstructor,
|
|
19
|
+
} from "./constructors.js";
|
|
20
|
+
import { parseExpr } from "./expressions.js";
|
|
21
|
+
import { parseArgumentList, parseKeySpecifier } from "./postfix.js";
|
|
22
|
+
import { isPlainName, qName } from "./tokenStream.js";
|
|
23
|
+
|
|
24
|
+
/** @typedef {import("./tokenStream.js").TokenStream} TokenStream */
|
|
25
|
+
/** @typedef {import("./ast.js").Expr} Expr */
|
|
26
|
+
|
|
27
|
+
/** Unprefixed names that are not function names (XPath 3.1 A.3). */
|
|
28
|
+
export const RESERVED_FUNCTION_NAMES = new Set(
|
|
29
|
+
(
|
|
30
|
+
"array attribute comment document-node element empty-sequence function " +
|
|
31
|
+
"if item map namespace-node node processing-instruction schema-attribute " +
|
|
32
|
+
"schema-element switch text typeswitch"
|
|
33
|
+
).split(" "),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* PrimaryExpr: literals, variable references, parenthesized expressions,
|
|
38
|
+
* `.`, function calls and references, constructors and `?key`.
|
|
39
|
+
*
|
|
40
|
+
* @param {TokenStream} p - Tokens
|
|
41
|
+
* @returns {Expr} The expression
|
|
42
|
+
*/
|
|
43
|
+
export function parsePrimaryExpr(p) {
|
|
44
|
+
const token = p.peek();
|
|
45
|
+
switch (token.type) {
|
|
46
|
+
case "integer":
|
|
47
|
+
case "decimal":
|
|
48
|
+
case "double":
|
|
49
|
+
p.next();
|
|
50
|
+
return makeNode(
|
|
51
|
+
"NumericLiteral",
|
|
52
|
+
{ kind: token.type, value: token.value },
|
|
53
|
+
token.start,
|
|
54
|
+
token.end,
|
|
55
|
+
);
|
|
56
|
+
case "string":
|
|
57
|
+
p.next();
|
|
58
|
+
return makeNode(
|
|
59
|
+
"StringLiteral",
|
|
60
|
+
{ value: token.value },
|
|
61
|
+
token.start,
|
|
62
|
+
token.end,
|
|
63
|
+
);
|
|
64
|
+
case "name":
|
|
65
|
+
return parseNamedPrimary(p);
|
|
66
|
+
}
|
|
67
|
+
if (p.isSymbol("$")) return parseVarRef(p);
|
|
68
|
+
if (p.isSymbol("(")) return parseParenthesizedExpr(p);
|
|
69
|
+
if (p.isSymbol("[")) return parseSquareArrayConstructor(p);
|
|
70
|
+
if (p.acceptSymbol(".")) {
|
|
71
|
+
return makeNode("ContextItemExpr", {}, token.start, token.end);
|
|
72
|
+
}
|
|
73
|
+
if (p.acceptSymbol("?")) {
|
|
74
|
+
const { keyKind, key, end } = parseKeySpecifier(p);
|
|
75
|
+
return makeNode("UnaryLookup", { keyKind, key }, token.start, end);
|
|
76
|
+
}
|
|
77
|
+
return p.fail("Expected an expression");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* A primary expression that starts with a name: `f#2`, `function(...)`,
|
|
82
|
+
* `map {...}`, `array {...}` or a function call. Plain names never get
|
|
83
|
+
* here: the path parser makes name tests of them.
|
|
84
|
+
*
|
|
85
|
+
* @param {TokenStream} p - Tokens
|
|
86
|
+
* @returns {Expr} The expression
|
|
87
|
+
*/
|
|
88
|
+
function parseNamedPrimary(p) {
|
|
89
|
+
const token = p.peek();
|
|
90
|
+
if (p.isKeyword("function") && p.isSymbol("(", 1)) {
|
|
91
|
+
return parseInlineFunctionExpr(p);
|
|
92
|
+
}
|
|
93
|
+
if (p.isSymbol("{", 1)) {
|
|
94
|
+
if (p.isKeyword("map")) return parseMapConstructor(p);
|
|
95
|
+
if (p.isKeyword("array")) return parseCurlyArrayConstructor(p);
|
|
96
|
+
}
|
|
97
|
+
if (isPlainName(token) && RESERVED_FUNCTION_NAMES.has(token.local)) {
|
|
98
|
+
p.fail("Reserved name used as a function name");
|
|
99
|
+
}
|
|
100
|
+
p.next();
|
|
101
|
+
if (p.acceptSymbol("#")) {
|
|
102
|
+
const arity = p.peek();
|
|
103
|
+
if (arity.type !== "integer") {
|
|
104
|
+
p.fail("Expected the arity, an integer literal");
|
|
105
|
+
}
|
|
106
|
+
p.next();
|
|
107
|
+
return makeNode(
|
|
108
|
+
"NamedFunctionRef",
|
|
109
|
+
{ name: qName(token), arity: Number(arity.value) },
|
|
110
|
+
token.start,
|
|
111
|
+
arity.end,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
const { arguments: args, end } = parseArgumentList(p);
|
|
115
|
+
return makeNode(
|
|
116
|
+
"FunctionCall",
|
|
117
|
+
{ name: qName(token), arguments: args },
|
|
118
|
+
token.start,
|
|
119
|
+
end,
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* ParenthesizedExpr ::= "(" Expr? ")"; `()` gives an EmptySequence, `(E)`
|
|
125
|
+
* the node of E.
|
|
126
|
+
*
|
|
127
|
+
* @param {TokenStream} p - Tokens, at "("
|
|
128
|
+
* @returns {Expr} The expression
|
|
129
|
+
*/
|
|
130
|
+
export function parseParenthesizedExpr(p) {
|
|
131
|
+
const open = p.expectSymbol("(");
|
|
132
|
+
const close = p.acceptSymbol(")");
|
|
133
|
+
if (close) return makeNode("EmptySequence", {}, open.start, close.end);
|
|
134
|
+
const expr = parseExpr(p);
|
|
135
|
+
p.expectSymbol(")");
|
|
136
|
+
return expr;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* VarRef ::= "$" VarName
|
|
141
|
+
*
|
|
142
|
+
* @param {TokenStream} p - Tokens, at "$"
|
|
143
|
+
* @returns {import("./ast.js").VarRef} The reference
|
|
144
|
+
*/
|
|
145
|
+
export function parseVarRef(p) {
|
|
146
|
+
const dollar = p.expectSymbol("$");
|
|
147
|
+
const name = p.expectName("a variable name");
|
|
148
|
+
return makeNode("VarRef", { name: qName(name) }, dollar.start, name.end);
|
|
149
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser of XPath 3.1 steps: productions [38] StepExpr to [52]
|
|
3
|
+
* PredicateList of Appendix A.1 (axes, abbreviations, node tests,
|
|
4
|
+
* predicates).
|
|
5
|
+
*
|
|
6
|
+
* @module @tradik/xslt3/xpath/syntax/steps
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { makeNode } from "./ast.js";
|
|
10
|
+
import { parseExpr } from "./expressions.js";
|
|
11
|
+
import { isKindTestName, parseKindTest } from "./kindTests.js";
|
|
12
|
+
import { parsePostfixExpr } from "./postfix.js";
|
|
13
|
+
import { isPlainName, qName } from "./tokenStream.js";
|
|
14
|
+
|
|
15
|
+
/** @typedef {import("./tokenStream.js").TokenStream} TokenStream */
|
|
16
|
+
/** @typedef {import("./ast.js").Expr} Expr */
|
|
17
|
+
|
|
18
|
+
/** The 13 axes of XPath 3.1, namespace included. */
|
|
19
|
+
const AXES = new Set(
|
|
20
|
+
(
|
|
21
|
+
"child descendant attribute self descendant-or-self following-sibling " +
|
|
22
|
+
"following namespace parent ancestor preceding-sibling preceding " +
|
|
23
|
+
"ancestor-or-self"
|
|
24
|
+
).split(" "),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* StepExpr ::= PostfixExpr | AxisStep
|
|
29
|
+
*
|
|
30
|
+
* @param {TokenStream} p - Tokens
|
|
31
|
+
* @returns {Expr} The step
|
|
32
|
+
*/
|
|
33
|
+
export function parseStepExpr(p) {
|
|
34
|
+
const token = p.peek();
|
|
35
|
+
if (p.isSymbol("..")) {
|
|
36
|
+
p.next();
|
|
37
|
+
const nodeTest = makeNode("AnyKindTest", {}, token.start, token.end);
|
|
38
|
+
return finishStep(p, "parent", nodeTest, token.start);
|
|
39
|
+
}
|
|
40
|
+
if (p.isSymbol("@")) {
|
|
41
|
+
p.next();
|
|
42
|
+
return finishStep(p, "attribute", parseNodeTest(p), token.start);
|
|
43
|
+
}
|
|
44
|
+
if (token.type === "name" && p.isSymbol("::", 1)) {
|
|
45
|
+
if (!isPlainName(token) || !AXES.has(token.local)) p.fail("Unknown axis");
|
|
46
|
+
p.next();
|
|
47
|
+
p.next();
|
|
48
|
+
return finishStep(p, token.local, parseNodeTest(p), token.start);
|
|
49
|
+
}
|
|
50
|
+
if (startsNodeTest(p)) {
|
|
51
|
+
const nodeTest = parseNodeTest(p);
|
|
52
|
+
return finishStep(p, defaultAxis(nodeTest), nodeTest, token.start);
|
|
53
|
+
}
|
|
54
|
+
return parsePostfixExpr(p);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Whether an abbreviated step (no axis) starts here, rather than a primary
|
|
59
|
+
* expression such as a function call, `f#1`, `map {}` or `array {}`.
|
|
60
|
+
*
|
|
61
|
+
* @param {TokenStream} p - Tokens
|
|
62
|
+
* @returns {boolean} True for a name test, wildcard or kind test
|
|
63
|
+
*/
|
|
64
|
+
function startsNodeTest(p) {
|
|
65
|
+
const token = p.peek();
|
|
66
|
+
if (token.type === "wildcard" || p.isSymbol("*")) return true;
|
|
67
|
+
if (token.type !== "name") return false;
|
|
68
|
+
if (p.isSymbol("(", 1)) return isKindTestName(token);
|
|
69
|
+
if (p.isSymbol("#", 1)) return false;
|
|
70
|
+
const constructor = p.isKeyword("map") || p.isKeyword("array");
|
|
71
|
+
return !(constructor && p.isSymbol("{", 1));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Default axis of an abbreviated step (XPath 3.1 section 3.3.5).
|
|
76
|
+
*
|
|
77
|
+
* @param {import("./typeAst.js").NodeTest} nodeTest - Test of the step
|
|
78
|
+
* @returns {string} "attribute", "namespace" or "child"
|
|
79
|
+
*/
|
|
80
|
+
function defaultAxis(nodeTest) {
|
|
81
|
+
switch (nodeTest.type) {
|
|
82
|
+
case "AttributeTest":
|
|
83
|
+
case "SchemaAttributeTest":
|
|
84
|
+
return "attribute";
|
|
85
|
+
case "NamespaceNodeTest":
|
|
86
|
+
return "namespace";
|
|
87
|
+
default:
|
|
88
|
+
return "child";
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* NodeTest ::= KindTest | NameTest, NameTest being an EQName or a Wildcard.
|
|
94
|
+
*
|
|
95
|
+
* @param {TokenStream} p - Tokens
|
|
96
|
+
* @returns {import("./typeAst.js").NodeTest} The test
|
|
97
|
+
*/
|
|
98
|
+
function parseNodeTest(p) {
|
|
99
|
+
const token = p.peek();
|
|
100
|
+
if (token.type === "name" && p.isSymbol("(", 1) && isKindTestName(token)) {
|
|
101
|
+
return parseKindTest(p);
|
|
102
|
+
}
|
|
103
|
+
if (token.type === "wildcard" || p.isSymbol("*")) {
|
|
104
|
+
p.next();
|
|
105
|
+
const fields =
|
|
106
|
+
token.type === "wildcard"
|
|
107
|
+
? qName(token)
|
|
108
|
+
: { prefix: null, local: null, uri: null };
|
|
109
|
+
return makeNode("Wildcard", fields, token.start, token.end);
|
|
110
|
+
}
|
|
111
|
+
const name = p.expectName("a node test");
|
|
112
|
+
return makeNode("NameTest", { name: qName(name) }, name.start, name.end);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Reads the predicates of an axis step and builds the step.
|
|
117
|
+
*
|
|
118
|
+
* @param {TokenStream} p - Tokens
|
|
119
|
+
* @param {string} axis - Axis name
|
|
120
|
+
* @param {import("./typeAst.js").NodeTest} nodeTest - Node test
|
|
121
|
+
* @param {number} start - Offset of the step
|
|
122
|
+
* @returns {import("./ast.js").AxisStep} The step
|
|
123
|
+
*/
|
|
124
|
+
function finishStep(p, axis, nodeTest, start) {
|
|
125
|
+
const predicates = [];
|
|
126
|
+
let end = nodeTest.end;
|
|
127
|
+
while (p.isSymbol("[")) {
|
|
128
|
+
const { predicate, end: predicateEnd } = parsePredicate(p);
|
|
129
|
+
predicates.push(predicate);
|
|
130
|
+
end = predicateEnd;
|
|
131
|
+
}
|
|
132
|
+
return makeNode("AxisStep", { axis, nodeTest, predicates }, start, end);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Predicate ::= "[" Expr "]"
|
|
137
|
+
*
|
|
138
|
+
* @param {TokenStream} p - Tokens, at "["
|
|
139
|
+
* @returns {{predicate: Expr, end: number}} The expression and the offset
|
|
140
|
+
* after "]"
|
|
141
|
+
*/
|
|
142
|
+
export function parsePredicate(p) {
|
|
143
|
+
p.expectSymbol("[");
|
|
144
|
+
const predicate = parseExpr(p);
|
|
145
|
+
return { predicate, end: p.expectSymbol("]").end };
|
|
146
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Construction of XPath static errors that point into the source text.
|
|
3
|
+
*
|
|
4
|
+
* @module @tradik/xslt3/xpath/syntax/syntaxError
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { XPathError } from "../../errors.js";
|
|
8
|
+
|
|
9
|
+
/** Characters of context shown on each side of the error offset. */
|
|
10
|
+
const EXCERPT_RADIUS = 20;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Builds an error whose message names the offset and shows the source around
|
|
14
|
+
* it, with "^" marking the offset, e.g. `... at offset 4: "1 + ^)"`.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} source - The whole expression
|
|
17
|
+
* @param {number} offset - Offset (UTF-16 code units) where the problem is
|
|
18
|
+
* @param {string} message - What is wrong
|
|
19
|
+
* @param {string} [code] - Error code, XPST0003 (syntax error) by default
|
|
20
|
+
* @returns {XPathError} The error, for the caller to throw
|
|
21
|
+
*/
|
|
22
|
+
export function syntaxError(source, offset, message, code = "XPST0003") {
|
|
23
|
+
const from = Math.max(0, offset - EXCERPT_RADIUS);
|
|
24
|
+
const to = Math.min(source.length, offset + EXCERPT_RADIUS);
|
|
25
|
+
const before = (from > 0 ? "..." : "") + source.slice(from, offset);
|
|
26
|
+
const after = source.slice(offset, to) + (to < source.length ? "..." : "");
|
|
27
|
+
return new XPathError(
|
|
28
|
+
code,
|
|
29
|
+
`${message} at offset ${offset}: ${JSON.stringify(before + "^" + after)}`,
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor over the tokens of one expression, shared by the parser modules.
|
|
3
|
+
*
|
|
4
|
+
* Keywords are recognised here by spelling only: a keyword is an unprefixed
|
|
5
|
+
* name token without a braced URI, so `fn:div` or `Q{}div` never are.
|
|
6
|
+
*
|
|
7
|
+
* @module @tradik/xslt3/xpath/syntax/tokenStream
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { tokenize } from "./lexer.js";
|
|
11
|
+
import { syntaxError } from "./syntaxError.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Describes a token for error messages.
|
|
15
|
+
*
|
|
16
|
+
* @param {import("./lexer.js").Token} token - Token
|
|
17
|
+
* @param {string} source - The expression
|
|
18
|
+
* @returns {string} e.g. `")"` or "end of expression"
|
|
19
|
+
*/
|
|
20
|
+
function describe(token, source) {
|
|
21
|
+
if (token.type === "eof") return "end of expression";
|
|
22
|
+
return JSON.stringify(source.slice(token.start, token.end));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Tokens of an expression with a read position. */
|
|
26
|
+
export class TokenStream {
|
|
27
|
+
/**
|
|
28
|
+
* @param {string} source - XPath expression
|
|
29
|
+
* @param {object} [options] - Parser options (see parseXPath)
|
|
30
|
+
*/
|
|
31
|
+
constructor(source, options = {}) {
|
|
32
|
+
this.source = source;
|
|
33
|
+
this.options = options;
|
|
34
|
+
this.tokens = tokenize(source);
|
|
35
|
+
this.index = 0;
|
|
36
|
+
/** Offset after the last consumed token. */
|
|
37
|
+
this.lastEnd = 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {number} [ahead] - 0 for the current token, 1 for the next...
|
|
42
|
+
* @returns {import("./lexer.js").Token} The token (eof past the end)
|
|
43
|
+
*/
|
|
44
|
+
peek(ahead = 0) {
|
|
45
|
+
const last = this.tokens.length - 1;
|
|
46
|
+
return this.tokens[Math.min(this.index + ahead, last)];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** @returns {import("./lexer.js").Token} The current token, consumed. */
|
|
50
|
+
next() {
|
|
51
|
+
const token = this.peek();
|
|
52
|
+
if (token.type !== "eof") this.index++;
|
|
53
|
+
this.lastEnd = token.end;
|
|
54
|
+
return token;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {string} value - Symbol, e.g. "("
|
|
59
|
+
* @param {number} [ahead] - Lookahead distance
|
|
60
|
+
* @returns {boolean} Whether that token is the symbol
|
|
61
|
+
*/
|
|
62
|
+
isSymbol(value, ahead = 0) {
|
|
63
|
+
const token = this.peek(ahead);
|
|
64
|
+
return token.type === "symbol" && token.value === value;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param {string} word - Keyword, e.g. "div"
|
|
69
|
+
* @param {number} [ahead] - Lookahead distance
|
|
70
|
+
* @returns {boolean} Whether that token is the keyword
|
|
71
|
+
*/
|
|
72
|
+
isKeyword(word, ahead = 0) {
|
|
73
|
+
const token = this.peek(ahead);
|
|
74
|
+
return isPlainName(token) && token.local === word;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Consumes the current token when it is the symbol.
|
|
79
|
+
*
|
|
80
|
+
* @param {string} value - Symbol
|
|
81
|
+
* @returns {import("./lexer.js").Token|null} The token, or null
|
|
82
|
+
*/
|
|
83
|
+
acceptSymbol(value) {
|
|
84
|
+
return this.isSymbol(value) ? this.next() : null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Consumes the current token when it is the keyword.
|
|
89
|
+
*
|
|
90
|
+
* @param {string} word - Keyword
|
|
91
|
+
* @returns {import("./lexer.js").Token|null} The token, or null
|
|
92
|
+
*/
|
|
93
|
+
acceptKeyword(word) {
|
|
94
|
+
return this.isKeyword(word) ? this.next() : null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Consumes the symbol or fails.
|
|
99
|
+
*
|
|
100
|
+
* @param {string} value - Expected symbol
|
|
101
|
+
* @returns {import("./lexer.js").Token} The token
|
|
102
|
+
*/
|
|
103
|
+
expectSymbol(value) {
|
|
104
|
+
return this.acceptSymbol(value) ?? this.fail(`Expected "${value}"`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Consumes the keyword or fails.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} word - Expected keyword
|
|
111
|
+
* @returns {import("./lexer.js").Token} The token
|
|
112
|
+
*/
|
|
113
|
+
expectKeyword(word) {
|
|
114
|
+
return this.acceptKeyword(word) ?? this.fail(`Expected "${word}"`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Consumes a name token (NCName, QName or EQName) or fails.
|
|
119
|
+
*
|
|
120
|
+
* @param {string} [what] - What the name is, for the message
|
|
121
|
+
* @returns {import("./lexer.js").Token} The token
|
|
122
|
+
*/
|
|
123
|
+
expectName(what = "a name") {
|
|
124
|
+
if (this.peek().type !== "name") this.fail(`Expected ${what}`);
|
|
125
|
+
return this.next();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Throws XPST0003 (or another code) at the current token.
|
|
130
|
+
*
|
|
131
|
+
* @param {string} message - What was expected
|
|
132
|
+
* @param {import("./lexer.js").Token} [token] - Offending token
|
|
133
|
+
* @param {string} [code] - Error code
|
|
134
|
+
* @returns {never}
|
|
135
|
+
*/
|
|
136
|
+
fail(message, token = this.peek(), code = undefined) {
|
|
137
|
+
const found = describe(token, this.source);
|
|
138
|
+
throw syntaxError(
|
|
139
|
+
this.source,
|
|
140
|
+
token.start,
|
|
141
|
+
`${message}, found ${found}`,
|
|
142
|
+
code,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @param {import("./lexer.js").Token} token - Token
|
|
149
|
+
* @returns {boolean} Whether it is a name without prefix and braced URI
|
|
150
|
+
*/
|
|
151
|
+
export function isPlainName(token) {
|
|
152
|
+
return token.type === "name" && token.prefix === null && token.uri === null;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The QName fields of a name or wildcard token, as kept in the AST.
|
|
157
|
+
*
|
|
158
|
+
* @param {import("./lexer.js").Token} token - Name token
|
|
159
|
+
* @returns {import("./ast.js").QName} `{ prefix, local, uri }`
|
|
160
|
+
*/
|
|
161
|
+
export function qName(token) {
|
|
162
|
+
return { prefix: token.prefix, local: token.local, uri: token.uri };
|
|
163
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The XPath 3.1 abstract syntax tree: node tests, item types and sequence
|
|
3
|
+
* types. Same conventions as ast.js (`{ type, ...fields, start, end }`).
|
|
4
|
+
* This module holds type definitions only.
|
|
5
|
+
*
|
|
6
|
+
* @module @tradik/xslt3/xpath/syntax/typeAst
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** @typedef {import("./ast.js").QName} QName */
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* `ItemType occurrence`; `itemType` null means `empty-sequence()`.
|
|
13
|
+
* `occurrence` is "" (exactly one), "?", "*" or "+".
|
|
14
|
+
*
|
|
15
|
+
* @typedef {{type: "SequenceType", itemType: ItemType|null, occurrence: ""|"?"|"*"|"+", start: number, end: number}} SequenceType
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Any item type. A parenthesized item type `(T)` leaves no node.
|
|
20
|
+
*
|
|
21
|
+
* @typedef {KindTest|AnyItemTest|AtomicType|AnyFunctionTest|TypedFunctionTest|
|
|
22
|
+
* AnyMapTest|TypedMapTest|AnyArrayTest|TypedArrayTest} ItemType
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** @typedef {NameTest|Wildcard|KindTest} NodeTest Test of an axis step */
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {AnyKindTest|DocumentTest|ElementTest|AttributeTest|
|
|
29
|
+
* SchemaElementTest|SchemaAttributeTest|PITest|CommentTest|TextTest|
|
|
30
|
+
* NamespaceNodeTest} KindTest
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/** @typedef {{type: "NameTest", name: QName, start: number, end: number}} NameTest */
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Wildcard name test: `*` (all fields null), `prefix:*` (prefix set),
|
|
37
|
+
* `*:local` (local set) or `Q{uri}*` (uri set, possibly "").
|
|
38
|
+
*
|
|
39
|
+
* @typedef {{type: "Wildcard", prefix: string|null, local: string|null, uri: string|null, start: number, end: number}} Wildcard
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/** @typedef {{type: "AnyKindTest", start: number, end: number}} AnyKindTest `node()` */
|
|
43
|
+
/** @typedef {{type: "DocumentTest", elementTest: ElementTest|SchemaElementTest|null, start: number, end: number}} DocumentTest `document-node(...)` */
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* `element()`, `element(name)`, `element(*, type)`, `element(name, type?)`.
|
|
47
|
+
* `name` null stands for `*` (or no name), `typeName` null for no type;
|
|
48
|
+
* `nillable` is true for the trailing `?`.
|
|
49
|
+
*
|
|
50
|
+
* @typedef {{type: "ElementTest", name: QName|null, typeName: QName|null, nillable: boolean, start: number, end: number}} ElementTest
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/** @typedef {{type: "AttributeTest", name: QName|null, typeName: QName|null, start: number, end: number}} AttributeTest `attribute(name-or-*, type)` */
|
|
54
|
+
/** @typedef {{type: "SchemaElementTest", name: QName, start: number, end: number}} SchemaElementTest */
|
|
55
|
+
/** @typedef {{type: "SchemaAttributeTest", name: QName, start: number, end: number}} SchemaAttributeTest */
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `processing-instruction(target)`; a string literal target is stored
|
|
59
|
+
* whitespace-normalized; null when there is no target.
|
|
60
|
+
*
|
|
61
|
+
* @typedef {{type: "PITest", target: string|null, start: number, end: number}} PITest
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/** @typedef {{type: "CommentTest", start: number, end: number}} CommentTest `comment()` */
|
|
65
|
+
/** @typedef {{type: "TextTest", start: number, end: number}} TextTest `text()` */
|
|
66
|
+
/** @typedef {{type: "NamespaceNodeTest", start: number, end: number}} NamespaceNodeTest `namespace-node()` */
|
|
67
|
+
/** @typedef {{type: "AnyItemTest", start: number, end: number}} AnyItemTest `item()` */
|
|
68
|
+
/** @typedef {{type: "AtomicType", name: QName, start: number, end: number}} AtomicType AtomicOrUnionType, e.g. `xs:integer` */
|
|
69
|
+
/** @typedef {{type: "AnyFunctionTest", start: number, end: number}} AnyFunctionTest `function(*)` */
|
|
70
|
+
/** @typedef {{type: "TypedFunctionTest", paramTypes: SequenceType[], returnType: SequenceType, start: number, end: number}} TypedFunctionTest `function(T1, T2) as R` */
|
|
71
|
+
/** @typedef {{type: "AnyMapTest", start: number, end: number}} AnyMapTest `map(*)` */
|
|
72
|
+
/** @typedef {{type: "TypedMapTest", keyType: AtomicType, valueType: SequenceType, start: number, end: number}} TypedMapTest `map(K, V)` */
|
|
73
|
+
/** @typedef {{type: "AnyArrayTest", start: number, end: number}} AnyArrayTest `array(*)` */
|
|
74
|
+
/** @typedef {{type: "TypedArrayTest", memberType: SequenceType, start: number, end: number}} TypedArrayTest `array(T)` */
|
|
75
|
+
|
|
76
|
+
export {};
|