parseman 0.39.1 → 0.40.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.
@@ -2730,12 +2730,30 @@ function isCstChild(value) {
2730
2730
  function missingInferredType() {
2731
2731
  throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
2732
2732
  }
2733
+ function normalizeProject(project) {
2734
+ if (project === void 0) return void 0;
2735
+ if (!Number.isInteger(project) || project < 0) {
2736
+ throw new Error("node() project child must be a non-negative integer");
2737
+ }
2738
+ return project;
2739
+ }
2740
+ function projectChild(children, project, type) {
2741
+ if (!(project in children)) {
2742
+ throw new Error(`node(${JSON.stringify(type)}) project child ${project} was not captured`);
2743
+ }
2744
+ return unwrapChild(children[project]);
2745
+ }
2733
2746
  function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
2734
2747
  const hasExplicitType = typeof typeOrCombinator === "string";
2735
2748
  const type = hasExplicitType ? typeOrCombinator : void 0;
2736
2749
  const combinator = hasExplicitType ? combinatorOrBuild : typeOrCombinator;
2737
- const build = hasExplicitType ? buildOrOpts : combinatorOrBuild;
2738
- const opts = hasExplicitType ? maybeOpts : buildOrOpts;
2750
+ const buildArg = hasExplicitType ? buildOrOpts : combinatorOrBuild;
2751
+ const build = typeof buildArg === "function" ? buildArg : void 0;
2752
+ const opts = typeof buildArg === "function" ? maybeOpts : buildArg ?? maybeOpts;
2753
+ const project = normalizeProject(opts?.project);
2754
+ if (project !== void 0 && build !== void 0) {
2755
+ throw new Error("node() options cannot combine project with a build callback");
2756
+ }
2739
2757
  const baseDef = { tag: "node", parser: combinator, ...type === void 0 ? {} : { type }, ...build === void 0 ? {} : { build } };
2740
2758
  const meta = {
2741
2759
  firstSet: combinator._meta.firstSet,
@@ -2749,11 +2767,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
2749
2767
  if (unwrap && collapse) {
2750
2768
  throw new Error("node() options cannot set both unwrap and collapse");
2751
2769
  }
2752
- const def = unwrap || collapse || captureTrivia || trailingTrivia ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {} } : baseDef;
2753
- const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : true);
2754
- const clonesState = build ? buildReadsState(def) : true;
2770
+ if (project !== void 0 && (unwrap || collapse)) {
2771
+ throw new Error("node() options cannot combine project with unwrap or collapse");
2772
+ }
2773
+ const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {} } : baseDef;
2774
+ const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
2775
+ const clonesState = build ? buildReadsState(def) : project === void 0;
2755
2776
  const hasOwnFields = parserHasOwnFields(combinator);
2756
- const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : true);
2777
+ const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
2757
2778
  const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
2758
2779
  let failExpected;
2759
2780
  return {
@@ -2768,14 +2789,15 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
2768
2789
  }
2769
2790
  return { ok: false, expected: failExpected, span: { start: pos, end: pos } };
2770
2791
  }
2771
- const hostCst = build !== void 0 && cstOutputHost(ctx.build);
2792
+ const hasDirectValue = build !== void 0 || project !== void 0;
2793
+ const hostCst = hasDirectValue && cstOutputHost(ctx.build);
2772
2794
  const effTrivia = capturesTrivia || hostCst;
2773
2795
  const effFields = capturesFields || hostCst && hasOwnFields;
2774
2796
  const saved = beginCstNodeCapture(ctx);
2775
2797
  const savedFields = ctx._fields;
2776
2798
  ctx._fields = effFields ? [] : void 0;
2777
2799
  const savedMask = ctx._triviaCaptureMask;
2778
- if (build === void 0 && ctx.build?._parsemanTriviaKinds !== void 0 && def.type !== void 0) {
2800
+ if (build === void 0 && project === void 0 && ctx.build?._parsemanTriviaKinds !== void 0 && def.type !== void 0) {
2779
2801
  ctx._triviaCaptureMask = ctx.build._parsemanTriviaKinds(def.type);
2780
2802
  }
2781
2803
  if (!effTrivia) ctx.captureTrivia = false;
@@ -2793,7 +2815,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
2793
2815
  const nodeType = def.type ?? missingInferredType();
2794
2816
  const cstOutput = cstOutputHost(ctx.build);
2795
2817
  const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
2796
- const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : !build && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : build ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, hostState) : build(children, fields, r.span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: { start: r.span.start, end: r.span.end }, state: st ?? null, children };
2818
+ const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, hostState) : projectChild(children, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, hostState) : build(children, fields, r.span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: { start: r.span.start, end: r.span.end }, state: st ?? null, children };
2797
2819
  const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span: r.span };
2798
2820
  if (saved.buf !== void 0 || saved.ch !== void 0) {
2799
2821
  pushCstChild(ctx, built, rawEntry);