@markuplint/pug-parser 4.0.0-dev.20 → 4.0.0-dev.23

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-2023 Yusuke Hirao
3
+ Copyright (c) 2017-2024 Yusuke Hirao
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/lib/index.d.ts CHANGED
@@ -1,2 +1 @@
1
- export { parse } from './parse.js';
2
- export declare const endTag = "never";
1
+ export { parser } from './parser.js';
package/lib/index.js CHANGED
@@ -1,2 +1 @@
1
- export { parse } from './parse.js';
2
- export const endTag = 'never';
1
+ export { parser } from './parser.js';
@@ -0,0 +1,29 @@
1
+ import type { ASTNode } from './pug-parser/index.js';
2
+ import type { MLASTAttr, MLASTNodeTreeItem, MLASTParentNode } from '@markuplint/ml-ast';
3
+ import type { ChildToken, Token } from '@markuplint/parser-utils';
4
+ import { ParserError, Parser } from '@markuplint/parser-utils';
5
+ declare class PugParser extends Parser<ASTNode> {
6
+ constructor();
7
+ tokenize(): {
8
+ ast: ASTNode[];
9
+ isFragment: boolean;
10
+ };
11
+ parseError(error: any): ParserError;
12
+ nodeize(originNode: ASTNode, parentNode: MLASTParentNode | null, depth: number): readonly MLASTNodeTreeItem[];
13
+ afterFlattenNodes(nodeList: readonly MLASTNodeTreeItem[]): readonly MLASTNodeTreeItem[];
14
+ visitElement(token: ChildToken & {
15
+ readonly nodeName: string;
16
+ readonly namespace: string;
17
+ }, childNodes: readonly ASTNode[], options: {
18
+ readonly overwriteProps: {
19
+ readonly attributes: readonly MLASTAttr[];
20
+ };
21
+ }): MLASTNodeTreeItem[];
22
+ visitAttr(token: Token): (import("@markuplint/ml-ast").MLASTHTMLAttr & {
23
+ __rightText?: string | undefined;
24
+ }) | (import("@markuplint/ml-ast").MLASTSpreadAttr & {
25
+ __rightText?: string | undefined;
26
+ });
27
+ }
28
+ export declare const parser: PugParser;
29
+ export {};
package/lib/parser.js ADDED
@@ -0,0 +1,162 @@
1
+ import { getNamespace, parser as htmlParser } from '@markuplint/html-parser';
2
+ import { ParserError, Parser, AttrState, removeQuote, scriptParser } from '@markuplint/parser-utils';
3
+ import { pugParse } from './pug-parser/index.js';
4
+ class PugParser extends Parser {
5
+ constructor() {
6
+ super({
7
+ endTagType: 'never',
8
+ });
9
+ }
10
+ tokenize() {
11
+ return {
12
+ ast: pugParse(this.rawCode).nodes,
13
+ isFragment: true,
14
+ };
15
+ }
16
+ parseError(error) {
17
+ if (error instanceof Error && 'msg' in error && 'line' in error && 'column' in error && 'src' in error) {
18
+ return new ParserError(error.msg, {
19
+ line: error.line,
20
+ col: error.column,
21
+ raw: error.src,
22
+ });
23
+ }
24
+ return super.parseError(error);
25
+ }
26
+ nodeize(
27
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
28
+ originNode, parentNode, depth) {
29
+ const parentNamespace = parentNode && 'namespace' in parentNode ? parentNode.namespace : 'http://www.w3.org/1999/xhtml';
30
+ const token = this.sliceFragment(originNode.offset, originNode.endOffset);
31
+ switch (originNode.type) {
32
+ case 'Doctype': {
33
+ return this.visitDoctype({
34
+ ...token,
35
+ depth,
36
+ parentNode,
37
+ name: originNode.val ?? '',
38
+ publicId: '',
39
+ systemId: '',
40
+ });
41
+ }
42
+ case 'Text': {
43
+ if (originNode.raw.trim() === '') {
44
+ return [];
45
+ }
46
+ const htmlDoc = htmlParser.parse(originNode.raw, {
47
+ offsetOffset: originNode.offset,
48
+ offsetLine: originNode.line,
49
+ offsetColumn: originNode.column,
50
+ depth,
51
+ });
52
+ return htmlDoc.nodeList;
53
+ }
54
+ case 'Comment': {
55
+ return this.visitComment({
56
+ ...token,
57
+ depth,
58
+ parentNode,
59
+ }, {
60
+ isBogus: false,
61
+ });
62
+ }
63
+ case 'Tag': {
64
+ const namespace = getNamespace(originNode.name, parentNamespace);
65
+ return this.visitElement({
66
+ ...token,
67
+ depth,
68
+ parentNode,
69
+ nodeName: originNode.name,
70
+ namespace,
71
+ }, originNode.block.nodes, {
72
+ overwriteProps: {
73
+ attributes: originNode.attrs.map(attr => {
74
+ const token = this.sliceFragment(attr.offset, attr.endOffset);
75
+ return this.visitAttr(token);
76
+ }),
77
+ },
78
+ });
79
+ }
80
+ default: {
81
+ return this.visitPsBlock({
82
+ ...token,
83
+ depth,
84
+ parentNode,
85
+ nodeName: originNode.type,
86
+ }, 'block' in originNode && originNode.block ? originNode.block.nodes : []);
87
+ }
88
+ }
89
+ }
90
+ afterFlattenNodes(nodeList) {
91
+ return super.afterFlattenNodes(nodeList, {
92
+ exposeInvalidNode: false,
93
+ exposeWhiteSpace: false,
94
+ });
95
+ }
96
+ visitElement(token,
97
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
98
+ childNodes, options) {
99
+ const startTag = {
100
+ ...token,
101
+ ...this.createToken(token),
102
+ ...options.overwriteProps,
103
+ type: 'starttag',
104
+ elementType: this.detectElementType(token.nodeName),
105
+ childNodes: [],
106
+ pairNode: null,
107
+ tagOpenChar: '',
108
+ tagCloseChar: '',
109
+ isGhost: false,
110
+ };
111
+ const siblings = this.visitChildren(childNodes, startTag);
112
+ return [startTag, ...siblings];
113
+ }
114
+ visitAttr(token) {
115
+ if (token.raw[0] === '#' || token.raw[0] === '.') {
116
+ const attr = super.visitAttr(token, {
117
+ startState: AttrState.BeforeValue,
118
+ quoteSet: [],
119
+ quoteInValueChars: [],
120
+ endOfUnquotedValueChars: [],
121
+ });
122
+ if (attr.type === 'spread') {
123
+ return attr;
124
+ }
125
+ this.updateAttr(attr, {
126
+ potentialName: token.raw[0] === '#' ? 'id' : 'class',
127
+ potentialValue: attr.value.raw.slice(1),
128
+ isDuplicatable: attr.potentialName === 'class',
129
+ });
130
+ return attr;
131
+ }
132
+ const attr = super.visitAttr(token, {
133
+ quoteSet: [],
134
+ quoteInValueChars: [],
135
+ endOfUnquotedValueChars: [],
136
+ });
137
+ if (attr.type === 'spread') {
138
+ return attr;
139
+ }
140
+ if (attr.name.raw.toLowerCase() === 'class') {
141
+ this.updateAttr(attr, { isDuplicatable: true });
142
+ }
143
+ const valueCodeTokens = scriptParser(attr.value.raw.trim());
144
+ if (valueCodeTokens.length === 1) {
145
+ const token = valueCodeTokens[0];
146
+ if (token.type === 'Numeric' || token.type === 'Boolean') {
147
+ this.updateAttr(attr, { potentialValue: token.value });
148
+ }
149
+ else if (token.type === 'String' || token.type === 'Template') {
150
+ this.updateAttr(attr, { potentialValue: removeQuote(token.value) });
151
+ }
152
+ else {
153
+ this.updateAttr(attr, { isDynamicValue: true });
154
+ }
155
+ }
156
+ else {
157
+ this.updateAttr(attr, { isDynamicValue: true });
158
+ }
159
+ return attr;
160
+ }
161
+ }
162
+ export const parser = new PugParser();
@@ -7,8 +7,6 @@ export function pugParse(pug) {
7
7
  const lexOrigin = lexer(pug);
8
8
  const lex = JSON.parse(JSON.stringify(lexOrigin));
9
9
  const originAst = parser(lexOrigin);
10
- // console.log(lex);
11
- // console.log(JSON.stringify(originAst, null, 2));
12
10
  const ast = optimizeAST(originAst, lex, pug);
13
11
  return ast;
14
12
  }
@@ -292,8 +290,9 @@ tokens, pug) {
292
290
  continue;
293
291
  }
294
292
  default: {
293
+ throw new Error(`Unsupported syntax: The "${
295
294
  // @ts-ignore
296
- throw new Error(`Unsupported syntax: The "${node.type}" node\n${JSON.stringify(node, null, 2)}`);
295
+ node.type}" node\n${JSON.stringify(node, null, 2)}`);
297
296
  }
298
297
  }
299
298
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/pug-parser",
3
- "version": "4.0.0-dev.20+6b35da16",
3
+ "version": "4.0.0-dev.23+d6f2aa9bc",
4
4
  "description": "Pug parser for markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -21,11 +21,11 @@
21
21
  "clean": "tsc --build --clean"
22
22
  },
23
23
  "dependencies": {
24
- "@markuplint/html-parser": "4.0.0-dev.20+6b35da16",
25
- "@markuplint/ml-ast": "4.0.0-dev.20+6b35da16",
26
- "@markuplint/parser-utils": "4.0.0-dev.20+6b35da16",
24
+ "@markuplint/html-parser": "4.0.0-dev.23+d6f2aa9bc",
25
+ "@markuplint/ml-ast": "4.0.0-dev.23+d6f2aa9bc",
26
+ "@markuplint/parser-utils": "4.0.0-dev.23+d6f2aa9bc",
27
27
  "pug-lexer": "^5.0.1",
28
28
  "pug-parser": "^6.0.0"
29
29
  },
30
- "gitHead": "6b35da161d94f784953d0adecc2d28502052d92a"
30
+ "gitHead": "d6f2aa9bc287768466f23b5340e4e0eecfa30d59"
31
31
  }
@@ -1,3 +0,0 @@
1
- import type { ASTAttr } from './pug-parser/index.js';
2
- import type { MLASTAttr } from '@markuplint/ml-ast';
3
- export declare function attrTokenizer(attr: ASTAttr): MLASTAttr;
@@ -1,134 +0,0 @@
1
- import { tokenizer, uuid, scriptParser, removeQuote } from '@markuplint/parser-utils';
2
- export function attrTokenizer(
3
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
4
- attr) {
5
- if (attr.raw[0] === '#' || attr.raw[0] === '.') {
6
- const value = `${attr.val}`;
7
- const potentialValue = removeQuote(value);
8
- return {
9
- type: 'ps-attr',
10
- uuid: uuid(),
11
- raw: attr.raw,
12
- startOffset: attr.offset,
13
- endOffset: attr.endOffset,
14
- startLine: attr.line,
15
- endLine: attr.endLine,
16
- startCol: attr.column,
17
- endCol: attr.endColumn,
18
- potentialName: attr.name,
19
- potentialValue,
20
- valueType: 'string',
21
- isDuplicatable: attr.raw[0] === '.',
22
- nodeName: '#pug-special-attr',
23
- parentNode: null,
24
- nextNode: null,
25
- prevNode: null,
26
- isFragment: false,
27
- isGhost: false,
28
- };
29
- }
30
- const spacesBeforeAttrString = '';
31
- const nameChars = attr.name;
32
- let spacesBeforeEqualChars;
33
- let equalChars;
34
- let spacesAfterEqualChars;
35
- const quoteChars = '';
36
- let valueChars;
37
- let potentialValue;
38
- let isDynamicValue = undefined;
39
- if (attr.val === true) {
40
- spacesBeforeEqualChars = '';
41
- equalChars = '';
42
- spacesAfterEqualChars = '';
43
- valueChars = '';
44
- potentialValue = '';
45
- }
46
- else {
47
- const withoutName = attr.raw.slice(attr.name.length);
48
- const valueOffset = withoutName.indexOf(attr.val);
49
- const equalAndBeforeSpaceAfterSpace = withoutName.slice(0, valueOffset);
50
- const [, before, equal, after] = equalAndBeforeSpaceAfterSpace.match(/^(\s*)(=)(\s*)$/) ?? ['', '', '', ''];
51
- const valueTokens = scriptParser(attr.val);
52
- spacesBeforeEqualChars = before ?? '';
53
- equalChars = equal ?? '';
54
- spacesAfterEqualChars = after ?? '';
55
- valueChars = attr.val;
56
- potentialValue = removeQuote(attr.val);
57
- if (valueTokens.length > 1 || valueTokens[0].type !== 'String') {
58
- isDynamicValue = true;
59
- }
60
- }
61
- const invalid = !!(valueChars && quoteChars === null && /["'<=>`]/.test(valueChars)) ||
62
- !!(equalChars && quoteChars === null && valueChars === null);
63
- if (invalid) {
64
- throw new Error('Parse error: It has invalid attribute');
65
- }
66
- let offset = attr.offset;
67
- let line = attr.line;
68
- let col = attr.column;
69
- const attrToken = tokenizer(attr.raw, line, col, offset);
70
- const spacesBeforeName = tokenizer(spacesBeforeAttrString, line, col, offset);
71
- line = spacesBeforeName.endLine;
72
- col = spacesBeforeName.endCol;
73
- offset = spacesBeforeName.endOffset;
74
- const name = tokenizer(nameChars, line, col, offset);
75
- line = name.endLine;
76
- col = name.endCol;
77
- offset = name.endOffset;
78
- const spacesBeforeEqual = tokenizer(spacesBeforeEqualChars, line, col, offset);
79
- line = spacesBeforeEqual.endLine;
80
- col = spacesBeforeEqual.endCol;
81
- offset = spacesBeforeEqual.endOffset;
82
- const equal = tokenizer(equalChars, line, col, offset);
83
- line = equal.endLine;
84
- col = equal.endCol;
85
- offset = equal.endOffset;
86
- const spacesAfterEqual = tokenizer(spacesAfterEqualChars, line, col, offset);
87
- line = spacesAfterEqual.endLine;
88
- col = spacesAfterEqual.endCol;
89
- offset = spacesAfterEqual.endOffset;
90
- const startQuote = tokenizer(quoteChars, line, col, offset);
91
- line = startQuote.endLine;
92
- col = startQuote.endCol;
93
- offset = startQuote.endOffset;
94
- const value = tokenizer(valueChars, line, col, offset);
95
- line = value.endLine;
96
- col = value.endCol;
97
- offset = value.endOffset;
98
- const endQuote = tokenizer(quoteChars, line, col, offset);
99
- line = endQuote.endLine;
100
- col = endQuote.endCol;
101
- offset = endQuote.endOffset;
102
- let isDuplicatable = false;
103
- if (name.raw.toLowerCase() === 'class') {
104
- isDuplicatable = true;
105
- }
106
- return {
107
- type: 'html-attr',
108
- uuid: uuid(),
109
- raw: attrToken.raw,
110
- startOffset: attrToken.startOffset,
111
- endOffset: attrToken.endOffset,
112
- startLine: attrToken.startLine,
113
- endLine: attrToken.endLine,
114
- startCol: attrToken.startCol,
115
- endCol: attrToken.endCol,
116
- spacesBeforeName,
117
- name,
118
- spacesBeforeEqual,
119
- equal,
120
- spacesAfterEqual,
121
- startQuote,
122
- value,
123
- endQuote,
124
- isDynamicValue,
125
- isDuplicatable,
126
- potentialValue,
127
- nodeName: name.raw,
128
- parentNode: null,
129
- nextNode: null,
130
- prevNode: null,
131
- isFragment: false,
132
- isGhost: false,
133
- };
134
- }
package/lib/parse.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { Parse } from '@markuplint/ml-ast';
2
- export declare const parse: Parse;
package/lib/parse.js DELETED
@@ -1,255 +0,0 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _Parser_ast;
13
- import { getNamespace, parse as htmlParse, isDocumentFragment } from '@markuplint/html-parser';
14
- import { detectElementType, ignoreFrontMatter, ParserError, tokenizer, uuid, walk, removeDeprecatedNode, } from '@markuplint/parser-utils';
15
- import { attrTokenizer } from './attr-tokenizer.js';
16
- import { pugParse } from './pug-parser/index.js';
17
- export const parse = (rawCode, options) => {
18
- let unknownParseError;
19
- let nodeList;
20
- if (options?.ignoreFrontMatter) {
21
- rawCode = ignoreFrontMatter(rawCode);
22
- }
23
- try {
24
- const parser = new Parser(rawCode);
25
- nodeList = parser.getNodeList();
26
- }
27
- catch (error) {
28
- nodeList = [];
29
- if (error instanceof Error && 'msg' in error && 'line' in error && 'column' in error && 'src' in error) {
30
- throw new ParserError(
31
- // @ts-ignore
32
- error.msg, {
33
- // @ts-ignore
34
- line: error.line,
35
- // @ts-ignore
36
- col: error.column,
37
- // @ts-ignore
38
- raw: error.src,
39
- });
40
- }
41
- unknownParseError = error instanceof Error ? error.message : new Error(`${error}`).message;
42
- }
43
- return {
44
- nodeList,
45
- isFragment: isDocumentFragment(rawCode),
46
- unknownParseError: unknownParseError,
47
- };
48
- };
49
- class Parser {
50
- constructor(raw) {
51
- _Parser_ast.set(this, void 0);
52
- __classPrivateFieldSet(this, _Parser_ast, pugParse(raw), "f");
53
- // console.log(JSON.stringify(this.#ast, null, 2));
54
- }
55
- flattenNodes(
56
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
57
- nodeTree) {
58
- const nodeOrders = [];
59
- walk(nodeTree, node => {
60
- nodeOrders.push(node);
61
- });
62
- removeDeprecatedNode(nodeOrders);
63
- return nodeOrders;
64
- }
65
- getNodeList() {
66
- const nodeTree = this.traverse(__classPrivateFieldGet(this, _Parser_ast, "f").nodes, null);
67
- return this.flattenNodes(nodeTree);
68
- }
69
- nodeize(
70
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
71
- originNode,
72
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
73
- prevNode,
74
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
75
- parentNode) {
76
- const nextNode = null;
77
- const startOffset = originNode.offset;
78
- const endOffset = originNode.endOffset;
79
- const startLine = originNode.line;
80
- const endLine = originNode.endLine;
81
- const startCol = originNode.column;
82
- const endCol = originNode.endColumn;
83
- const parentNamespace = parentNode && 'namespace' in parentNode ? parentNode.namespace : 'http://www.w3.org/1999/xhtml';
84
- switch (originNode.type) {
85
- case 'Doctype': {
86
- return {
87
- uuid: uuid(),
88
- raw: originNode.raw,
89
- name: originNode.val ?? '',
90
- // TODO:
91
- publicId: '',
92
- // TODO:
93
- systemId: '',
94
- startOffset,
95
- endOffset,
96
- startLine,
97
- endLine,
98
- startCol,
99
- endCol,
100
- nodeName: '#doctype',
101
- type: 'doctype',
102
- parentNode,
103
- prevNode,
104
- _addPrevNode: 102,
105
- nextNode,
106
- isFragment: false,
107
- isGhost: false,
108
- };
109
- }
110
- case 'Text': {
111
- if (parentNode && /^script$|^style$/i.test(parentNode.nodeName)) {
112
- return {
113
- uuid: uuid(),
114
- raw: originNode.raw,
115
- startOffset,
116
- endOffset,
117
- startLine,
118
- endLine,
119
- startCol,
120
- endCol,
121
- nodeName: '#text',
122
- type: 'text',
123
- parentNode,
124
- prevNode,
125
- nextNode,
126
- isFragment: false,
127
- isGhost: false,
128
- };
129
- }
130
- const htmlDoc = htmlParse(originNode.raw, {
131
- offsetOffset: originNode.offset,
132
- offsetLine: originNode.line - 1,
133
- offsetColumn: originNode.column - 1,
134
- });
135
- const nodes = htmlDoc.nodeList.filter(node => {
136
- return node.parentNode == null && node.type !== 'endtag';
137
- });
138
- return nodes;
139
- }
140
- case 'Comment': {
141
- return {
142
- uuid: uuid(),
143
- raw: originNode.raw,
144
- startOffset,
145
- endOffset,
146
- startLine,
147
- endLine,
148
- startCol,
149
- endCol,
150
- nodeName: '#comment',
151
- type: 'comment',
152
- parentNode,
153
- prevNode,
154
- nextNode,
155
- isFragment: false,
156
- isGhost: false,
157
- };
158
- }
159
- case 'Tag': {
160
- const namespace = getNamespace(originNode.name, parentNamespace);
161
- const tag = {
162
- uuid: uuid(),
163
- raw: originNode.raw,
164
- startOffset,
165
- endOffset,
166
- startLine,
167
- endLine,
168
- startCol,
169
- endCol,
170
- nodeName: originNode.name,
171
- type: 'starttag',
172
- namespace,
173
- elementType: detectElementType(originNode.name),
174
- attributes: originNode.attrs.map(attr => attrTokenizer(attr)),
175
- hasSpreadAttr: false,
176
- parentNode,
177
- prevNode,
178
- nextNode,
179
- pearNode: null,
180
- selfClosingSolidus: tokenizer('', originNode.line, originNode.column, originNode.offset),
181
- endSpace: tokenizer('', originNode.line, originNode.column, originNode.offset),
182
- isFragment: false,
183
- isGhost: false,
184
- tagOpenChar: '',
185
- tagCloseChar: '',
186
- };
187
- if (originNode.block.nodes.length > 0) {
188
- tag.childNodes = this.traverse(originNode.block.nodes, tag);
189
- }
190
- return tag;
191
- }
192
- default: {
193
- const tag = {
194
- uuid: uuid(),
195
- raw: originNode.raw,
196
- startOffset,
197
- endOffset,
198
- startLine,
199
- endLine,
200
- startCol,
201
- endCol,
202
- type: 'psblock',
203
- nodeName: originNode.type,
204
- parentNode,
205
- prevNode,
206
- nextNode,
207
- isFragment: true,
208
- isGhost: false,
209
- };
210
- if ('block' in originNode && originNode.block && originNode.block.nodes.length > 0) {
211
- tag.childNodes = this.traverse(originNode.block.nodes, tag);
212
- }
213
- return tag;
214
- }
215
- }
216
- }
217
- traverse(
218
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
219
- astNodes, parentNode = null) {
220
- const nodeList = [];
221
- let prevNode = null;
222
- for (const astNode of astNodes) {
223
- const nodes = this.nodeize(astNode, prevNode, parentNode);
224
- if (!nodes || (Array.isArray(nodes) && nodes.length === 0)) {
225
- continue;
226
- }
227
- let node;
228
- if (Array.isArray(nodes)) {
229
- const lastNode = nodes.at(-1);
230
- if (!lastNode) {
231
- continue;
232
- }
233
- node = lastNode;
234
- }
235
- else {
236
- node = nodes;
237
- }
238
- if (prevNode) {
239
- if (node.type !== 'endtag') {
240
- prevNode.nextNode = node;
241
- }
242
- node.prevNode = prevNode;
243
- }
244
- prevNode = node;
245
- if (Array.isArray(nodes)) {
246
- nodeList.push(...nodes);
247
- }
248
- else {
249
- nodeList.push(nodes);
250
- }
251
- }
252
- return nodeList;
253
- }
254
- }
255
- _Parser_ast = new WeakMap();