• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ota-meshi / astro-eslint-parser / 29175963174

12 Jul 2026 01:54AM UTC coverage: 81.67% (-0.1%) from 81.788%
29175963174

push

github

web-flow
feat!: use `@astrojs/compiler-rs` instead of `@astrojs/compiler` (#435)

* feat!: use `@astrojs/compiler-rs` instead of `@astrojs/compiler`

* Create kind-plants-drive.md

* fix: ts errors

* fix

* update

* update

* update

* fix: typings

* fix

* fix

* fix: some bugs

* update

* update

651 of 867 branches covered (75.09%)

Branch coverage included in aggregate %.

349 of 395 new or added lines in 9 files covered. (88.35%)

6 existing lines in 4 files now uncovered.

1256 of 1468 relevant lines covered (85.56%)

52551.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.74
/src/astro/walker.ts
1
import { getKeys } from "../traverse";
1,572!
2
import { isNode } from "./node";
1✔
3
import type {
4
  AstroCommentNode,
5
  AstroDoctypeNode,
6
  AstroFrontmatterNode,
7
  AstroRootNode,
8
  JSXElementNode,
9
  JSXFragmentNode,
10
  UnknownNode,
11
} from "./types";
12

13
export type WalkContext = {
14
  /** Skip walking the children of the current node. */
15
  skipChildren: () => void;
16
  /** Stop walking entirely. */
17
  break: () => void;
18
};
19

20
/**
21
 * Walk the compiler AST.
22
 * The `enter` callback is called when entering a node, and the `leave` callback is called when leaving a node.
23
 * The `ctx` object passed to the callbacks has two methods: `skipChildren()` to skip walking the children of the current node, and `break()` to stop walking entirely.
24
 * The callbacks are called in depth-first order.
25
 */
26
export function walk(
1✔
27
  parent: UnknownNode,
28
  enter: (node: UnknownNode, parents: UnknownNode[], ctx: WalkContext) => void,
29
  leave?: (node: UnknownNode, parents: UnknownNode[], ctx: WalkContext) => void,
30
): void {
31
  const childNodes = getChildNodes(parent);
772✔
32

33
  const parents: UnknownNode[] = [parent];
772✔
34
  for (const child of childNodes) {
772✔
35
    if (
736!
36
      walkNode(
37
        child,
38
        enter,
39
        leave ||
1,472✔
40
          (() => {
41
            // noop
42
          }),
43
        parents,
44
      ).break
45
    ) {
NEW
46
      break;
×
47
    }
48
  }
49
}
50

51
/** Walk one compiler child node. */
52
function walkNode(
1✔
53
  node: UnknownNode,
54
  enter: (node: UnknownNode, parents: UnknownNode[], ctx: WalkContext) => void,
55
  leave: (node: UnknownNode, parents: UnknownNode[], ctx: WalkContext) => void,
56
  parents: UnknownNode[],
57
): { break?: boolean } {
58
  const buffer: { node: UnknownNode; parents: UnknownNode[] }[] = [
736✔
59
    { node, parents },
60
  ];
61

62
  let shouldBreak = false;
736✔
63
  let shouldSkipChildren = false;
736✔
64
  const currentCtx: WalkContext = {
736✔
65
    skipChildren() {
66
      shouldSkipChildren = true;
242✔
67
    },
68
    break() {
NEW
69
      shouldBreak = true;
×
70
    },
71
  };
72
  while (buffer.length > 0) {
736✔
73
    const current = buffer.pop()!;
2,175✔
74
    enter(current.node, current.parents, currentCtx);
2,175✔
75
    if (shouldBreak) return { break: true };
2,175!
76
    if (shouldSkipChildren) {
2,175✔
77
      shouldSkipChildren = false;
242✔
78
    } else {
79
      const childNodes = getChildNodes(current.node);
1,933✔
80

81
      const parents = [current.node, ...current.parents];
1,933✔
82
      for (let i = childNodes.length - 1; i >= 0; i--) {
1,933✔
83
        buffer.push({ node: childNodes[i], parents });
1,439✔
84
      }
85
    }
86
    leave(current.node, current.parents, currentCtx);
2,175✔
87
    if (shouldBreak) return { break: true };
2,175!
88
  }
89
  return {};
736✔
90
}
91

92
/**
93
 * Get child nodes of a compiler node.
94
 */
95
function getChildNodes(node: UnknownNode): UnknownNode[] {
1✔
96
  if (isAstroRoot(node)) {
2,705!
NEW
97
    return [...(node.frontmatter ? [node.frontmatter] : []), ...node.body].sort(
×
NEW
98
      (a, b) => a.start - b.start,
×
99
    );
100
  }
101
  if (isAstroFrontmatter(node)) {
2,705!
NEW
102
    return [node.program];
×
103
  }
104
  if (isAstroComment(node) || isAstroDoctype(node)) {
2,705!
NEW
105
    return [];
×
106
  }
107
  if (isJSXFragment(node)) {
2,705!
NEW
108
    return [
×
109
      node.openingFragment,
110
      ...node.children,
111
      ...(node.closingFragment ? [node.closingFragment] : []),
×
112
    ];
113
  }
114
  if (isJSXElement(node)) {
2,705!
NEW
115
    return [
×
116
      node.openingElement,
117
      ...node.children,
118
      ...(node.closingElement ? [node.closingElement] : []),
×
119
    ];
120
  }
121

122
  const keys = getKeys(node);
2,705✔
123
  const children: UnknownNode[] = [];
2,705✔
124
  for (const key of keys) {
2,705✔
125
    const value: unknown = (node as any)[key];
2,130✔
126
    if (Array.isArray(value)) {
2,130✔
127
      for (const element of value) {
441✔
128
        if (isNode(element)) {
486✔
129
          children.push(element);
486✔
130
        }
131
      }
132
    } else if (isNode(value)) {
1,689✔
133
      children.push(value);
1,689✔
134
    }
135
  }
136

137
  return children.sort((a, b) => a.start - b.start);
2,705✔
138
}
139

140
/** Check whether the given node is a JSX element */
141
function isJSXElement(node: UnknownNode): node is JSXElementNode {
1✔
142
  return node.type === "JSXElement";
2,705✔
143
}
144

145
/** Check whether the given node is a JSX fragment */
146
function isJSXFragment(node: UnknownNode): node is JSXFragmentNode {
1✔
147
  return node.type === "JSXFragment";
2,705✔
148
}
149

150
/** Check whether the given node is the root node of the Astro AST. */
151
function isAstroRoot(node: UnknownNode): node is AstroRootNode {
1✔
152
  return node.type === "AstroRoot";
2,705✔
153
}
154

155
/** Check whether the given node is a walkable template node. */
156
function isAstroFrontmatter(node: UnknownNode): node is AstroFrontmatterNode {
1✔
157
  return node.type === "AstroFrontmatter";
2,705✔
158
}
159

160
/** Check whether the given node is a walkable template node. */
161
function isAstroComment(node: UnknownNode): node is AstroCommentNode {
1✔
162
  return node.type === "AstroComment";
2,705✔
163
}
164

165
/** Check whether the given node is a walkable template node. */
166
function isAstroDoctype(node: UnknownNode): node is AstroDoctypeNode {
2!
167
  return node.type === "AstroDoctype";
2,705✔
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc