@herb-tools/core 0.9.0 → 0.9.1
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/dist/herb-core.browser.js +557 -10
- package/dist/herb-core.browser.js.map +1 -1
- package/dist/herb-core.cjs +570 -10
- package/dist/herb-core.cjs.map +1 -1
- package/dist/herb-core.esm.js +557 -10
- package/dist/herb-core.esm.js.map +1 -1
- package/dist/herb-core.umd.js +570 -10
- package/dist/herb-core.umd.js.map +1 -1
- package/dist/types/ast-utils.d.ts +2 -3
- package/dist/types/diagnostic.d.ts +6 -0
- package/dist/types/errors.d.ts +141 -1
- package/dist/types/node-type-guards.d.ts +19 -1
- package/dist/types/nodes.d.ts +115 -4
- package/dist/types/parser-options.d.ts +3 -0
- package/dist/types/visitor.d.ts +5 -1
- package/package.json +1 -1
- package/src/ast-utils.ts +3 -4
- package/src/diagnostic.ts +7 -0
- package/src/errors.ts +465 -17
- package/src/node-type-guards.ts +42 -1
- package/src/nodes.ts +322 -2
- package/src/parser-options.ts +6 -0
- package/src/visitor.ts +16 -1
|
@@ -69,7 +69,7 @@ export declare function hasStaticAttributeName(attributeNameNode: HTMLAttributeN
|
|
|
69
69
|
/**
|
|
70
70
|
* Checks if an HTML attribute name node has dynamic content (contains ERB)
|
|
71
71
|
*/
|
|
72
|
-
export declare function
|
|
72
|
+
export declare function hasDynamicAttributeNameNode(attributeNameNode: HTMLAttributeNameNode): boolean;
|
|
73
73
|
/**
|
|
74
74
|
* Gets the static string value of an HTML attribute name node
|
|
75
75
|
* Returns null if the attribute name contains dynamic content (ERB)
|
|
@@ -151,9 +151,8 @@ export declare function getAttribute(node: HTMLElementNode | HTMLOpenTagNode | n
|
|
|
151
151
|
export declare function hasAttribute(node: HTMLElementNode | HTMLOpenTagNode | null | undefined, attributeName: string): boolean;
|
|
152
152
|
/**
|
|
153
153
|
* Checks if an attribute has a dynamic (ERB-containing) name.
|
|
154
|
-
* Accepts an HTMLAttributeNode (wraps the core HTMLAttributeNameNode-level check).
|
|
155
154
|
*/
|
|
156
|
-
export declare function
|
|
155
|
+
export declare function hasDynamicAttributeName(attributeNode: HTMLAttributeNode): boolean;
|
|
157
156
|
/**
|
|
158
157
|
* Gets the combined string representation of an attribute name (including ERB syntax).
|
|
159
158
|
* Accepts an HTMLAttributeNode (wraps the core HTMLAttributeNameNode-level check).
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Location, SerializedLocation } from "./location.js";
|
|
2
2
|
export type DiagnosticSeverity = "error" | "warning" | "info" | "hint";
|
|
3
|
+
export type DiagnosticTag = "unnecessary" | "deprecated";
|
|
3
4
|
/**
|
|
4
5
|
* Base interface for all diagnostic information in Herb tooling.
|
|
5
6
|
* This includes parser errors, lexer errors, lint offenses, and any other
|
|
@@ -26,6 +27,10 @@ export interface Diagnostic {
|
|
|
26
27
|
* Optional source that generated this diagnostic (e.g., "parser", "linter", "lexer")
|
|
27
28
|
*/
|
|
28
29
|
source?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Optional diagnostic tags for additional metadata (e.g., "unnecessary", "deprecated")
|
|
32
|
+
*/
|
|
33
|
+
tags?: DiagnosticTag[];
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
36
|
* Serialized form of a Diagnostic for JSON representation
|
|
@@ -36,6 +41,7 @@ export interface SerializedDiagnostic {
|
|
|
36
41
|
severity: DiagnosticSeverity;
|
|
37
42
|
code?: string;
|
|
38
43
|
source?: string;
|
|
44
|
+
tags?: DiagnosticTag[];
|
|
39
45
|
}
|
|
40
46
|
export type MonacoSeverity = "error" | "warning" | "info";
|
|
41
47
|
/**
|
package/dist/types/errors.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Location, SerializedLocation } from "./location.js";
|
|
|
2
2
|
import { Position, SerializedPosition } from "./position.js";
|
|
3
3
|
import { Token, SerializedToken } from "./token.js";
|
|
4
4
|
import { Diagnostic, MonacoDiagnostic } from "./diagnostic.js";
|
|
5
|
-
export type HerbErrorType = "UNEXPECTED_ERROR" | "UNEXPECTED_TOKEN_ERROR" | "MISSING_OPENING_TAG_ERROR" | "MISSING_CLOSING_TAG_ERROR" | "TAG_NAMES_MISMATCH_ERROR" | "VOID_ELEMENT_CLOSING_TAG_ERROR" | "UNCLOSED_ELEMENT_ERROR" | "RUBY_PARSE_ERROR" | "ERB_CONTROL_FLOW_SCOPE_ERROR" | "MISSING_ERB_END_TAG_ERROR" | "ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR" | "ERB_CASE_WITH_CONDITIONS_ERROR" | "CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR" | "CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR" | "INVALID_COMMENT_CLOSING_TAG_ERROR" | "OMITTED_CLOSING_TAG_ERROR" | "UNCLOSED_OPEN_TAG_ERROR" | "UNCLOSED_CLOSE_TAG_ERROR" | "UNCLOSED_QUOTE_ERROR" | "MISSING_ATTRIBUTE_VALUE_ERROR" | "UNCLOSED_ERB_TAG_ERROR" | "STRAY_ERB_CLOSING_TAG_ERROR" | "NESTED_ERB_TAG_ERROR";
|
|
5
|
+
export type HerbErrorType = "UNEXPECTED_ERROR" | "UNEXPECTED_TOKEN_ERROR" | "MISSING_OPENING_TAG_ERROR" | "MISSING_CLOSING_TAG_ERROR" | "TAG_NAMES_MISMATCH_ERROR" | "VOID_ELEMENT_CLOSING_TAG_ERROR" | "UNCLOSED_ELEMENT_ERROR" | "RUBY_PARSE_ERROR" | "ERB_CONTROL_FLOW_SCOPE_ERROR" | "MISSING_ERB_END_TAG_ERROR" | "ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR" | "ERB_CASE_WITH_CONDITIONS_ERROR" | "CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR" | "CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR" | "INVALID_COMMENT_CLOSING_TAG_ERROR" | "OMITTED_CLOSING_TAG_ERROR" | "UNCLOSED_OPEN_TAG_ERROR" | "UNCLOSED_CLOSE_TAG_ERROR" | "UNCLOSED_QUOTE_ERROR" | "MISSING_ATTRIBUTE_VALUE_ERROR" | "UNCLOSED_ERB_TAG_ERROR" | "STRAY_ERB_CLOSING_TAG_ERROR" | "NESTED_ERB_TAG_ERROR" | "RENDER_AMBIGUOUS_LOCALS_ERROR" | "RENDER_MISSING_LOCALS_ERROR" | "RENDER_NO_ARGUMENTS_ERROR" | "RENDER_CONFLICTING_PARTIAL_ERROR" | "RENDER_INVALID_AS_OPTION_ERROR" | "RENDER_OBJECT_AND_COLLECTION_ERROR" | "RENDER_LAYOUT_WITHOUT_BLOCK_ERROR";
|
|
6
6
|
export type SerializedErrorType = string;
|
|
7
7
|
export interface SerializedHerbError {
|
|
8
8
|
type: string;
|
|
@@ -527,4 +527,144 @@ export declare class NestedERBTagError extends HerbError {
|
|
|
527
527
|
toMonacoDiagnostic(): MonacoDiagnostic;
|
|
528
528
|
treeInspect(): string;
|
|
529
529
|
}
|
|
530
|
+
export interface SerializedRenderAmbiguousLocalsError {
|
|
531
|
+
type: "RENDER_AMBIGUOUS_LOCALS_ERROR";
|
|
532
|
+
message: string;
|
|
533
|
+
location: SerializedLocation;
|
|
534
|
+
partial: string;
|
|
535
|
+
}
|
|
536
|
+
export interface RenderAmbiguousLocalsErrorProps {
|
|
537
|
+
type: string;
|
|
538
|
+
message: string;
|
|
539
|
+
location: Location;
|
|
540
|
+
partial: string;
|
|
541
|
+
}
|
|
542
|
+
export declare class RenderAmbiguousLocalsError extends HerbError {
|
|
543
|
+
readonly partial: string;
|
|
544
|
+
static from(data: SerializedRenderAmbiguousLocalsError): RenderAmbiguousLocalsError;
|
|
545
|
+
constructor(props: RenderAmbiguousLocalsErrorProps);
|
|
546
|
+
toJSON(): SerializedRenderAmbiguousLocalsError;
|
|
547
|
+
toMonacoDiagnostic(): MonacoDiagnostic;
|
|
548
|
+
treeInspect(): string;
|
|
549
|
+
}
|
|
550
|
+
export interface SerializedRenderMissingLocalsError {
|
|
551
|
+
type: "RENDER_MISSING_LOCALS_ERROR";
|
|
552
|
+
message: string;
|
|
553
|
+
location: SerializedLocation;
|
|
554
|
+
partial: string;
|
|
555
|
+
keywords: string;
|
|
556
|
+
}
|
|
557
|
+
export interface RenderMissingLocalsErrorProps {
|
|
558
|
+
type: string;
|
|
559
|
+
message: string;
|
|
560
|
+
location: Location;
|
|
561
|
+
partial: string;
|
|
562
|
+
keywords: string;
|
|
563
|
+
}
|
|
564
|
+
export declare class RenderMissingLocalsError extends HerbError {
|
|
565
|
+
readonly partial: string;
|
|
566
|
+
readonly keywords: string;
|
|
567
|
+
static from(data: SerializedRenderMissingLocalsError): RenderMissingLocalsError;
|
|
568
|
+
constructor(props: RenderMissingLocalsErrorProps);
|
|
569
|
+
toJSON(): SerializedRenderMissingLocalsError;
|
|
570
|
+
toMonacoDiagnostic(): MonacoDiagnostic;
|
|
571
|
+
treeInspect(): string;
|
|
572
|
+
}
|
|
573
|
+
export interface SerializedRenderNoArgumentsError {
|
|
574
|
+
type: "RENDER_NO_ARGUMENTS_ERROR";
|
|
575
|
+
message: string;
|
|
576
|
+
location: SerializedLocation;
|
|
577
|
+
}
|
|
578
|
+
export interface RenderNoArgumentsErrorProps {
|
|
579
|
+
type: string;
|
|
580
|
+
message: string;
|
|
581
|
+
location: Location;
|
|
582
|
+
}
|
|
583
|
+
export declare class RenderNoArgumentsError extends HerbError {
|
|
584
|
+
static from(data: SerializedRenderNoArgumentsError): RenderNoArgumentsError;
|
|
585
|
+
constructor(props: RenderNoArgumentsErrorProps);
|
|
586
|
+
toJSON(): SerializedRenderNoArgumentsError;
|
|
587
|
+
toMonacoDiagnostic(): MonacoDiagnostic;
|
|
588
|
+
treeInspect(): string;
|
|
589
|
+
}
|
|
590
|
+
export interface SerializedRenderConflictingPartialError {
|
|
591
|
+
type: "RENDER_CONFLICTING_PARTIAL_ERROR";
|
|
592
|
+
message: string;
|
|
593
|
+
location: SerializedLocation;
|
|
594
|
+
positional_partial: string;
|
|
595
|
+
keyword_partial: string;
|
|
596
|
+
}
|
|
597
|
+
export interface RenderConflictingPartialErrorProps {
|
|
598
|
+
type: string;
|
|
599
|
+
message: string;
|
|
600
|
+
location: Location;
|
|
601
|
+
positional_partial: string;
|
|
602
|
+
keyword_partial: string;
|
|
603
|
+
}
|
|
604
|
+
export declare class RenderConflictingPartialError extends HerbError {
|
|
605
|
+
readonly positional_partial: string;
|
|
606
|
+
readonly keyword_partial: string;
|
|
607
|
+
static from(data: SerializedRenderConflictingPartialError): RenderConflictingPartialError;
|
|
608
|
+
constructor(props: RenderConflictingPartialErrorProps);
|
|
609
|
+
toJSON(): SerializedRenderConflictingPartialError;
|
|
610
|
+
toMonacoDiagnostic(): MonacoDiagnostic;
|
|
611
|
+
treeInspect(): string;
|
|
612
|
+
}
|
|
613
|
+
export interface SerializedRenderInvalidAsOptionError {
|
|
614
|
+
type: "RENDER_INVALID_AS_OPTION_ERROR";
|
|
615
|
+
message: string;
|
|
616
|
+
location: SerializedLocation;
|
|
617
|
+
as_value: string;
|
|
618
|
+
}
|
|
619
|
+
export interface RenderInvalidAsOptionErrorProps {
|
|
620
|
+
type: string;
|
|
621
|
+
message: string;
|
|
622
|
+
location: Location;
|
|
623
|
+
as_value: string;
|
|
624
|
+
}
|
|
625
|
+
export declare class RenderInvalidAsOptionError extends HerbError {
|
|
626
|
+
readonly as_value: string;
|
|
627
|
+
static from(data: SerializedRenderInvalidAsOptionError): RenderInvalidAsOptionError;
|
|
628
|
+
constructor(props: RenderInvalidAsOptionErrorProps);
|
|
629
|
+
toJSON(): SerializedRenderInvalidAsOptionError;
|
|
630
|
+
toMonacoDiagnostic(): MonacoDiagnostic;
|
|
631
|
+
treeInspect(): string;
|
|
632
|
+
}
|
|
633
|
+
export interface SerializedRenderObjectAndCollectionError {
|
|
634
|
+
type: "RENDER_OBJECT_AND_COLLECTION_ERROR";
|
|
635
|
+
message: string;
|
|
636
|
+
location: SerializedLocation;
|
|
637
|
+
}
|
|
638
|
+
export interface RenderObjectAndCollectionErrorProps {
|
|
639
|
+
type: string;
|
|
640
|
+
message: string;
|
|
641
|
+
location: Location;
|
|
642
|
+
}
|
|
643
|
+
export declare class RenderObjectAndCollectionError extends HerbError {
|
|
644
|
+
static from(data: SerializedRenderObjectAndCollectionError): RenderObjectAndCollectionError;
|
|
645
|
+
constructor(props: RenderObjectAndCollectionErrorProps);
|
|
646
|
+
toJSON(): SerializedRenderObjectAndCollectionError;
|
|
647
|
+
toMonacoDiagnostic(): MonacoDiagnostic;
|
|
648
|
+
treeInspect(): string;
|
|
649
|
+
}
|
|
650
|
+
export interface SerializedRenderLayoutWithoutBlockError {
|
|
651
|
+
type: "RENDER_LAYOUT_WITHOUT_BLOCK_ERROR";
|
|
652
|
+
message: string;
|
|
653
|
+
location: SerializedLocation;
|
|
654
|
+
layout: string;
|
|
655
|
+
}
|
|
656
|
+
export interface RenderLayoutWithoutBlockErrorProps {
|
|
657
|
+
type: string;
|
|
658
|
+
message: string;
|
|
659
|
+
location: Location;
|
|
660
|
+
layout: string;
|
|
661
|
+
}
|
|
662
|
+
export declare class RenderLayoutWithoutBlockError extends HerbError {
|
|
663
|
+
readonly layout: string;
|
|
664
|
+
static from(data: SerializedRenderLayoutWithoutBlockError): RenderLayoutWithoutBlockError;
|
|
665
|
+
constructor(props: RenderLayoutWithoutBlockErrorProps);
|
|
666
|
+
toJSON(): SerializedRenderLayoutWithoutBlockError;
|
|
667
|
+
toMonacoDiagnostic(): MonacoDiagnostic;
|
|
668
|
+
treeInspect(): string;
|
|
669
|
+
}
|
|
530
670
|
export declare function fromSerializedError(error: SerializedHerbError): HerbError;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Node, NodeType, ERBNode } from "./nodes.js";
|
|
2
2
|
import { Token } from "./token.js";
|
|
3
3
|
import { ParseResult } from "./parse-result.js";
|
|
4
|
-
import { DocumentNode, LiteralNode, HTMLOpenTagNode, HTMLConditionalOpenTagNode, HTMLCloseTagNode, HTMLOmittedCloseTagNode, HTMLVirtualCloseTagNode, HTMLElementNode, HTMLConditionalElementNode, HTMLAttributeValueNode, HTMLAttributeNameNode, HTMLAttributeNode, RubyLiteralNode, RubyHTMLAttributesSplatNode, ERBOpenTagNode, HTMLTextNode, HTMLCommentNode, HTMLDoctypeNode, XMLDeclarationNode, CDATANode, WhitespaceNode, ERBContentNode, ERBEndNode, ERBElseNode, ERBIfNode, ERBBlockNode, ERBWhenNode, ERBCaseNode, ERBCaseMatchNode, ERBWhileNode, ERBUntilNode, ERBForNode, ERBRescueNode, ERBEnsureNode, ERBBeginNode, ERBUnlessNode, ERBYieldNode, ERBInNode } from "./nodes.js";
|
|
4
|
+
import { DocumentNode, LiteralNode, HTMLOpenTagNode, HTMLConditionalOpenTagNode, HTMLCloseTagNode, HTMLOmittedCloseTagNode, HTMLVirtualCloseTagNode, HTMLElementNode, HTMLConditionalElementNode, HTMLAttributeValueNode, HTMLAttributeNameNode, HTMLAttributeNode, RubyLiteralNode, RubyHTMLAttributesSplatNode, ERBOpenTagNode, HTMLTextNode, HTMLCommentNode, HTMLDoctypeNode, XMLDeclarationNode, CDATANode, WhitespaceNode, ERBContentNode, ERBEndNode, ERBElseNode, ERBIfNode, ERBBlockNode, ERBWhenNode, ERBCaseNode, ERBCaseMatchNode, ERBWhileNode, ERBUntilNode, ERBForNode, ERBRescueNode, ERBEnsureNode, ERBBeginNode, ERBUnlessNode, RubyRenderLocalNode, ERBRenderNode, ERBYieldNode, ERBInNode } from "./nodes.js";
|
|
5
5
|
/**
|
|
6
6
|
* Type guard functions for AST nodes.
|
|
7
7
|
* These functions provide type checking by combining both instanceof
|
|
@@ -152,6 +152,14 @@ export declare function isERBBeginNode(node: Node | null | undefined): node is E
|
|
|
152
152
|
* Checks if a node is a ERBUnlessNode
|
|
153
153
|
*/
|
|
154
154
|
export declare function isERBUnlessNode(node: Node | null | undefined): node is ERBUnlessNode;
|
|
155
|
+
/**
|
|
156
|
+
* Checks if a node is a RubyRenderLocalNode
|
|
157
|
+
*/
|
|
158
|
+
export declare function isRubyRenderLocalNode(node: Node | null | undefined): node is RubyRenderLocalNode;
|
|
159
|
+
/**
|
|
160
|
+
* Checks if a node is a ERBRenderNode
|
|
161
|
+
*/
|
|
162
|
+
export declare function isERBRenderNode(node: Node | null | undefined): node is ERBRenderNode;
|
|
155
163
|
/**
|
|
156
164
|
* Checks if a node is a ERBYieldNode
|
|
157
165
|
*/
|
|
@@ -230,6 +238,8 @@ type NodeTypeToClass = {
|
|
|
230
238
|
"AST_ERB_ENSURE_NODE": ERBEnsureNode;
|
|
231
239
|
"AST_ERB_BEGIN_NODE": ERBBeginNode;
|
|
232
240
|
"AST_ERB_UNLESS_NODE": ERBUnlessNode;
|
|
241
|
+
"AST_RUBY_RENDER_LOCAL_NODE": RubyRenderLocalNode;
|
|
242
|
+
"AST_ERB_RENDER_NODE": ERBRenderNode;
|
|
233
243
|
"AST_ERB_YIELD_NODE": ERBYieldNode;
|
|
234
244
|
"AST_ERB_IN_NODE": ERBInNode;
|
|
235
245
|
};
|
|
@@ -486,6 +496,14 @@ export declare function filterERBBeginNodes(nodes: Node[]): ERBBeginNode[];
|
|
|
486
496
|
* Filters an array of nodes to only include ERBUnlessNode nodes
|
|
487
497
|
*/
|
|
488
498
|
export declare function filterERBUnlessNodes(nodes: Node[]): ERBUnlessNode[];
|
|
499
|
+
/**
|
|
500
|
+
* Filters an array of nodes to only include RubyRenderLocalNode nodes
|
|
501
|
+
*/
|
|
502
|
+
export declare function filterRubyRenderLocalNodes(nodes: Node[]): RubyRenderLocalNode[];
|
|
503
|
+
/**
|
|
504
|
+
* Filters an array of nodes to only include ERBRenderNode nodes
|
|
505
|
+
*/
|
|
506
|
+
export declare function filterERBRenderNodes(nodes: Node[]): ERBRenderNode[];
|
|
489
507
|
/**
|
|
490
508
|
* Filters an array of nodes to only include ERBYieldNode nodes
|
|
491
509
|
*/
|
package/dist/types/nodes.d.ts
CHANGED
|
@@ -1160,6 +1160,115 @@ export declare class ERBUnlessNode extends Node {
|
|
|
1160
1160
|
toJSON(): SerializedERBUnlessNode;
|
|
1161
1161
|
treeInspect(): string;
|
|
1162
1162
|
}
|
|
1163
|
+
export interface SerializedRubyRenderLocalNode extends SerializedNode {
|
|
1164
|
+
type: "AST_RUBY_RENDER_LOCAL_NODE";
|
|
1165
|
+
name: SerializedToken | null;
|
|
1166
|
+
value: SerializedRubyLiteralNode | null;
|
|
1167
|
+
}
|
|
1168
|
+
export interface RubyRenderLocalNodeProps extends Omit<BaseNodeProps, 'type'> {
|
|
1169
|
+
type: "AST_RUBY_RENDER_LOCAL_NODE";
|
|
1170
|
+
name: Token | null;
|
|
1171
|
+
value: RubyLiteralNode | null;
|
|
1172
|
+
}
|
|
1173
|
+
export declare class RubyRenderLocalNode extends Node {
|
|
1174
|
+
readonly type: "AST_RUBY_RENDER_LOCAL_NODE";
|
|
1175
|
+
readonly name: Token | null;
|
|
1176
|
+
readonly value: RubyLiteralNode | null;
|
|
1177
|
+
static get type(): NodeType;
|
|
1178
|
+
static from(data: SerializedRubyRenderLocalNode): RubyRenderLocalNode;
|
|
1179
|
+
constructor(props: RubyRenderLocalNodeProps);
|
|
1180
|
+
accept(visitor: Visitor): void;
|
|
1181
|
+
childNodes(): (Node | null | undefined)[];
|
|
1182
|
+
compactChildNodes(): Node[];
|
|
1183
|
+
recursiveErrors(): HerbError[];
|
|
1184
|
+
toJSON(): SerializedRubyRenderLocalNode;
|
|
1185
|
+
treeInspect(): string;
|
|
1186
|
+
}
|
|
1187
|
+
export interface SerializedERBRenderNode extends SerializedNode {
|
|
1188
|
+
type: "AST_ERB_RENDER_NODE";
|
|
1189
|
+
tag_opening: SerializedToken | null;
|
|
1190
|
+
content: SerializedToken | null;
|
|
1191
|
+
tag_closing: SerializedToken | null;
|
|
1192
|
+
prism_node: number[] | null;
|
|
1193
|
+
partial: SerializedToken | null;
|
|
1194
|
+
template_path: SerializedToken | null;
|
|
1195
|
+
layout: SerializedToken | null;
|
|
1196
|
+
file: SerializedToken | null;
|
|
1197
|
+
inline_template: SerializedToken | null;
|
|
1198
|
+
body: SerializedToken | null;
|
|
1199
|
+
plain: SerializedToken | null;
|
|
1200
|
+
html: SerializedToken | null;
|
|
1201
|
+
renderable: SerializedToken | null;
|
|
1202
|
+
collection: SerializedToken | null;
|
|
1203
|
+
object: SerializedToken | null;
|
|
1204
|
+
as_name: SerializedToken | null;
|
|
1205
|
+
spacer_template: SerializedToken | null;
|
|
1206
|
+
formats: SerializedToken | null;
|
|
1207
|
+
variants: SerializedToken | null;
|
|
1208
|
+
handlers: SerializedToken | null;
|
|
1209
|
+
content_type: SerializedToken | null;
|
|
1210
|
+
locals: SerializedNode[];
|
|
1211
|
+
}
|
|
1212
|
+
export interface ERBRenderNodeProps extends Omit<BaseNodeProps, 'type'> {
|
|
1213
|
+
type: "AST_ERB_RENDER_NODE";
|
|
1214
|
+
tag_opening: Token | null;
|
|
1215
|
+
content: Token | null;
|
|
1216
|
+
tag_closing: Token | null;
|
|
1217
|
+
prism_node: Uint8Array | null;
|
|
1218
|
+
partial: Token | null;
|
|
1219
|
+
template_path: Token | null;
|
|
1220
|
+
layout: Token | null;
|
|
1221
|
+
file: Token | null;
|
|
1222
|
+
inline_template: Token | null;
|
|
1223
|
+
body: Token | null;
|
|
1224
|
+
plain: Token | null;
|
|
1225
|
+
html: Token | null;
|
|
1226
|
+
renderable: Token | null;
|
|
1227
|
+
collection: Token | null;
|
|
1228
|
+
object: Token | null;
|
|
1229
|
+
as_name: Token | null;
|
|
1230
|
+
spacer_template: Token | null;
|
|
1231
|
+
formats: Token | null;
|
|
1232
|
+
variants: Token | null;
|
|
1233
|
+
handlers: Token | null;
|
|
1234
|
+
content_type: Token | null;
|
|
1235
|
+
locals: any[];
|
|
1236
|
+
}
|
|
1237
|
+
export declare class ERBRenderNode extends Node {
|
|
1238
|
+
readonly type: "AST_ERB_RENDER_NODE";
|
|
1239
|
+
readonly tag_opening: Token | null;
|
|
1240
|
+
readonly content: Token | null;
|
|
1241
|
+
readonly tag_closing: Token | null;
|
|
1242
|
+
readonly prism_node: Uint8Array | null;
|
|
1243
|
+
readonly partial: Token | null;
|
|
1244
|
+
readonly template_path: Token | null;
|
|
1245
|
+
readonly layout: Token | null;
|
|
1246
|
+
readonly file: Token | null;
|
|
1247
|
+
readonly inline_template: Token | null;
|
|
1248
|
+
readonly body: Token | null;
|
|
1249
|
+
readonly plain: Token | null;
|
|
1250
|
+
readonly html: Token | null;
|
|
1251
|
+
readonly renderable: Token | null;
|
|
1252
|
+
readonly collection: Token | null;
|
|
1253
|
+
readonly object: Token | null;
|
|
1254
|
+
readonly as_name: Token | null;
|
|
1255
|
+
readonly spacer_template: Token | null;
|
|
1256
|
+
readonly formats: Token | null;
|
|
1257
|
+
readonly variants: Token | null;
|
|
1258
|
+
readonly handlers: Token | null;
|
|
1259
|
+
readonly content_type: Token | null;
|
|
1260
|
+
readonly locals: Node[];
|
|
1261
|
+
static get type(): NodeType;
|
|
1262
|
+
static from(data: SerializedERBRenderNode): ERBRenderNode;
|
|
1263
|
+
constructor(props: ERBRenderNodeProps);
|
|
1264
|
+
accept(visitor: Visitor): void;
|
|
1265
|
+
childNodes(): (Node | null | undefined)[];
|
|
1266
|
+
compactChildNodes(): Node[];
|
|
1267
|
+
get prismNode(): PrismNode | null;
|
|
1268
|
+
recursiveErrors(): HerbError[];
|
|
1269
|
+
toJSON(): SerializedERBRenderNode;
|
|
1270
|
+
treeInspect(): string;
|
|
1271
|
+
}
|
|
1163
1272
|
export interface SerializedERBYieldNode extends SerializedNode {
|
|
1164
1273
|
type: "AST_ERB_YIELD_NODE";
|
|
1165
1274
|
tag_opening: SerializedToken | null;
|
|
@@ -1220,7 +1329,7 @@ export declare class ERBInNode extends Node {
|
|
|
1220
1329
|
toJSON(): SerializedERBInNode;
|
|
1221
1330
|
treeInspect(): string;
|
|
1222
1331
|
}
|
|
1223
|
-
export type ConcreteNode = DocumentNode | LiteralNode | HTMLOpenTagNode | HTMLConditionalOpenTagNode | HTMLCloseTagNode | HTMLOmittedCloseTagNode | HTMLVirtualCloseTagNode | HTMLElementNode | HTMLConditionalElementNode | HTMLAttributeValueNode | HTMLAttributeNameNode | HTMLAttributeNode | RubyLiteralNode | RubyHTMLAttributesSplatNode | ERBOpenTagNode | HTMLTextNode | HTMLCommentNode | HTMLDoctypeNode | XMLDeclarationNode | CDATANode | WhitespaceNode | ERBContentNode | ERBEndNode | ERBElseNode | ERBIfNode | ERBBlockNode | ERBWhenNode | ERBCaseNode | ERBCaseMatchNode | ERBWhileNode | ERBUntilNode | ERBForNode | ERBRescueNode | ERBEnsureNode | ERBBeginNode | ERBUnlessNode | ERBYieldNode | ERBInNode;
|
|
1332
|
+
export type ConcreteNode = DocumentNode | LiteralNode | HTMLOpenTagNode | HTMLConditionalOpenTagNode | HTMLCloseTagNode | HTMLOmittedCloseTagNode | HTMLVirtualCloseTagNode | HTMLElementNode | HTMLConditionalElementNode | HTMLAttributeValueNode | HTMLAttributeNameNode | HTMLAttributeNode | RubyLiteralNode | RubyHTMLAttributesSplatNode | ERBOpenTagNode | HTMLTextNode | HTMLCommentNode | HTMLDoctypeNode | XMLDeclarationNode | CDATANode | WhitespaceNode | ERBContentNode | ERBEndNode | ERBElseNode | ERBIfNode | ERBBlockNode | ERBWhenNode | ERBCaseNode | ERBCaseMatchNode | ERBWhileNode | ERBUntilNode | ERBForNode | ERBRescueNode | ERBEnsureNode | ERBBeginNode | ERBUnlessNode | RubyRenderLocalNode | ERBRenderNode | ERBYieldNode | ERBInNode;
|
|
1224
1333
|
export declare function fromSerializedNode(node: SerializedDocumentNode): DocumentNode;
|
|
1225
1334
|
export declare function fromSerializedNode(node: SerializedLiteralNode): LiteralNode;
|
|
1226
1335
|
export declare function fromSerializedNode(node: SerializedHTMLOpenTagNode): HTMLOpenTagNode;
|
|
@@ -1257,10 +1366,12 @@ export declare function fromSerializedNode(node: SerializedERBRescueNode): ERBRe
|
|
|
1257
1366
|
export declare function fromSerializedNode(node: SerializedERBEnsureNode): ERBEnsureNode;
|
|
1258
1367
|
export declare function fromSerializedNode(node: SerializedERBBeginNode): ERBBeginNode;
|
|
1259
1368
|
export declare function fromSerializedNode(node: SerializedERBUnlessNode): ERBUnlessNode;
|
|
1369
|
+
export declare function fromSerializedNode(node: SerializedRubyRenderLocalNode): RubyRenderLocalNode;
|
|
1370
|
+
export declare function fromSerializedNode(node: SerializedERBRenderNode): ERBRenderNode;
|
|
1260
1371
|
export declare function fromSerializedNode(node: SerializedERBYieldNode): ERBYieldNode;
|
|
1261
1372
|
export declare function fromSerializedNode(node: SerializedERBInNode): ERBInNode;
|
|
1262
1373
|
export declare function fromSerializedNode(node: SerializedNode): Node;
|
|
1263
|
-
export type NodeType = "AST_DOCUMENT_NODE" | "AST_LITERAL_NODE" | "AST_HTML_OPEN_TAG_NODE" | "AST_HTML_CONDITIONAL_OPEN_TAG_NODE" | "AST_HTML_CLOSE_TAG_NODE" | "AST_HTML_OMITTED_CLOSE_TAG_NODE" | "AST_HTML_VIRTUAL_CLOSE_TAG_NODE" | "AST_HTML_ELEMENT_NODE" | "AST_HTML_CONDITIONAL_ELEMENT_NODE" | "AST_HTML_ATTRIBUTE_VALUE_NODE" | "AST_HTML_ATTRIBUTE_NAME_NODE" | "AST_HTML_ATTRIBUTE_NODE" | "AST_RUBY_LITERAL_NODE" | "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE" | "AST_ERB_OPEN_TAG_NODE" | "AST_HTML_TEXT_NODE" | "AST_HTML_COMMENT_NODE" | "AST_HTML_DOCTYPE_NODE" | "AST_XML_DECLARATION_NODE" | "AST_CDATA_NODE" | "AST_WHITESPACE_NODE" | "AST_ERB_CONTENT_NODE" | "AST_ERB_END_NODE" | "AST_ERB_ELSE_NODE" | "AST_ERB_IF_NODE" | "AST_ERB_BLOCK_NODE" | "AST_ERB_WHEN_NODE" | "AST_ERB_CASE_NODE" | "AST_ERB_CASE_MATCH_NODE" | "AST_ERB_WHILE_NODE" | "AST_ERB_UNTIL_NODE" | "AST_ERB_FOR_NODE" | "AST_ERB_RESCUE_NODE" | "AST_ERB_ENSURE_NODE" | "AST_ERB_BEGIN_NODE" | "AST_ERB_UNLESS_NODE" | "AST_ERB_YIELD_NODE" | "AST_ERB_IN_NODE";
|
|
1374
|
+
export type NodeType = "AST_DOCUMENT_NODE" | "AST_LITERAL_NODE" | "AST_HTML_OPEN_TAG_NODE" | "AST_HTML_CONDITIONAL_OPEN_TAG_NODE" | "AST_HTML_CLOSE_TAG_NODE" | "AST_HTML_OMITTED_CLOSE_TAG_NODE" | "AST_HTML_VIRTUAL_CLOSE_TAG_NODE" | "AST_HTML_ELEMENT_NODE" | "AST_HTML_CONDITIONAL_ELEMENT_NODE" | "AST_HTML_ATTRIBUTE_VALUE_NODE" | "AST_HTML_ATTRIBUTE_NAME_NODE" | "AST_HTML_ATTRIBUTE_NODE" | "AST_RUBY_LITERAL_NODE" | "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE" | "AST_ERB_OPEN_TAG_NODE" | "AST_HTML_TEXT_NODE" | "AST_HTML_COMMENT_NODE" | "AST_HTML_DOCTYPE_NODE" | "AST_XML_DECLARATION_NODE" | "AST_CDATA_NODE" | "AST_WHITESPACE_NODE" | "AST_ERB_CONTENT_NODE" | "AST_ERB_END_NODE" | "AST_ERB_ELSE_NODE" | "AST_ERB_IF_NODE" | "AST_ERB_BLOCK_NODE" | "AST_ERB_WHEN_NODE" | "AST_ERB_CASE_NODE" | "AST_ERB_CASE_MATCH_NODE" | "AST_ERB_WHILE_NODE" | "AST_ERB_UNTIL_NODE" | "AST_ERB_FOR_NODE" | "AST_ERB_RESCUE_NODE" | "AST_ERB_ENSURE_NODE" | "AST_ERB_BEGIN_NODE" | "AST_ERB_UNLESS_NODE" | "AST_RUBY_RENDER_LOCAL_NODE" | "AST_ERB_RENDER_NODE" | "AST_ERB_YIELD_NODE" | "AST_ERB_IN_NODE";
|
|
1264
1375
|
export type ERBNodeType = Extract<NodeType, `AST_ERB_${string}`>;
|
|
1265
|
-
export type ERBNode = ERBOpenTagNode | ERBContentNode | ERBEndNode | ERBElseNode | ERBIfNode | ERBBlockNode | ERBWhenNode | ERBCaseNode | ERBCaseMatchNode | ERBWhileNode | ERBUntilNode | ERBForNode | ERBRescueNode | ERBEnsureNode | ERBBeginNode | ERBUnlessNode | ERBYieldNode | ERBInNode;
|
|
1266
|
-
export declare const ERBNodeClasses: (typeof ERBOpenTagNode | typeof ERBContentNode | typeof ERBEndNode | typeof ERBElseNode | typeof ERBIfNode | typeof ERBBlockNode | typeof ERBWhenNode | typeof ERBCaseNode | typeof ERBCaseMatchNode | typeof ERBWhileNode | typeof ERBUntilNode | typeof ERBForNode | typeof ERBRescueNode | typeof ERBEnsureNode | typeof ERBBeginNode | typeof ERBUnlessNode | typeof ERBYieldNode | typeof ERBInNode)[];
|
|
1376
|
+
export type ERBNode = ERBOpenTagNode | ERBContentNode | ERBEndNode | ERBElseNode | ERBIfNode | ERBBlockNode | ERBWhenNode | ERBCaseNode | ERBCaseMatchNode | ERBWhileNode | ERBUntilNode | ERBForNode | ERBRescueNode | ERBEnsureNode | ERBBeginNode | ERBUnlessNode | ERBRenderNode | ERBYieldNode | ERBInNode;
|
|
1377
|
+
export declare const ERBNodeClasses: (typeof ERBOpenTagNode | typeof ERBContentNode | typeof ERBEndNode | typeof ERBElseNode | typeof ERBIfNode | typeof ERBBlockNode | typeof ERBWhenNode | typeof ERBCaseNode | typeof ERBCaseMatchNode | typeof ERBWhileNode | typeof ERBUntilNode | typeof ERBForNode | typeof ERBRescueNode | typeof ERBEnsureNode | typeof ERBBeginNode | typeof ERBUnlessNode | typeof ERBRenderNode | typeof ERBYieldNode | typeof ERBInNode)[];
|
|
@@ -3,6 +3,7 @@ export interface ParseOptions {
|
|
|
3
3
|
analyze?: boolean;
|
|
4
4
|
strict?: boolean;
|
|
5
5
|
action_view_helpers?: boolean;
|
|
6
|
+
render_nodes?: boolean;
|
|
6
7
|
prism_nodes?: boolean;
|
|
7
8
|
prism_nodes_deep?: boolean;
|
|
8
9
|
prism_program?: boolean;
|
|
@@ -21,6 +22,8 @@ export declare class ParserOptions {
|
|
|
21
22
|
readonly analyze: boolean;
|
|
22
23
|
/** Whether ActionView tag helper transformation was enabled during parsing. */
|
|
23
24
|
readonly action_view_helpers: boolean;
|
|
25
|
+
/** Whether ActionView render call detection was enabled during parsing. */
|
|
26
|
+
readonly render_nodes: boolean;
|
|
24
27
|
/** Whether Prism node serialization was enabled during parsing. */
|
|
25
28
|
readonly prism_nodes: boolean;
|
|
26
29
|
/** Whether deep Prism node serialization was enabled during parsing. */
|
package/dist/types/visitor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Node, ERBNode, DocumentNode, LiteralNode, HTMLOpenTagNode, HTMLConditionalOpenTagNode, HTMLCloseTagNode, HTMLOmittedCloseTagNode, HTMLVirtualCloseTagNode, HTMLElementNode, HTMLConditionalElementNode, HTMLAttributeValueNode, HTMLAttributeNameNode, HTMLAttributeNode, RubyLiteralNode, RubyHTMLAttributesSplatNode, ERBOpenTagNode, HTMLTextNode, HTMLCommentNode, HTMLDoctypeNode, XMLDeclarationNode, CDATANode, WhitespaceNode, ERBContentNode, ERBEndNode, ERBElseNode, ERBIfNode, ERBBlockNode, ERBWhenNode, ERBCaseNode, ERBCaseMatchNode, ERBWhileNode, ERBUntilNode, ERBForNode, ERBRescueNode, ERBEnsureNode, ERBBeginNode, ERBUnlessNode, ERBYieldNode, ERBInNode } from "./nodes.js";
|
|
1
|
+
import { Node, ERBNode, DocumentNode, LiteralNode, HTMLOpenTagNode, HTMLConditionalOpenTagNode, HTMLCloseTagNode, HTMLOmittedCloseTagNode, HTMLVirtualCloseTagNode, HTMLElementNode, HTMLConditionalElementNode, HTMLAttributeValueNode, HTMLAttributeNameNode, HTMLAttributeNode, RubyLiteralNode, RubyHTMLAttributesSplatNode, ERBOpenTagNode, HTMLTextNode, HTMLCommentNode, HTMLDoctypeNode, XMLDeclarationNode, CDATANode, WhitespaceNode, ERBContentNode, ERBEndNode, ERBElseNode, ERBIfNode, ERBBlockNode, ERBWhenNode, ERBCaseNode, ERBCaseMatchNode, ERBWhileNode, ERBUntilNode, ERBForNode, ERBRescueNode, ERBEnsureNode, ERBBeginNode, ERBUnlessNode, RubyRenderLocalNode, ERBRenderNode, ERBYieldNode, ERBInNode } from "./nodes.js";
|
|
2
2
|
/**
|
|
3
3
|
* Interface that enforces all node visit methods are implemented
|
|
4
4
|
* This ensures that any class implementing IVisitor must have a visit method for every node type
|
|
@@ -43,6 +43,8 @@ export interface IVisitor {
|
|
|
43
43
|
visitERBEnsureNode(node: ERBEnsureNode): void;
|
|
44
44
|
visitERBBeginNode(node: ERBBeginNode): void;
|
|
45
45
|
visitERBUnlessNode(node: ERBUnlessNode): void;
|
|
46
|
+
visitRubyRenderLocalNode(node: RubyRenderLocalNode): void;
|
|
47
|
+
visitERBRenderNode(node: ERBRenderNode): void;
|
|
46
48
|
visitERBYieldNode(node: ERBYieldNode): void;
|
|
47
49
|
visitERBInNode(node: ERBInNode): void;
|
|
48
50
|
visitNode(node: Node): void;
|
|
@@ -90,6 +92,8 @@ export declare class Visitor implements IVisitor {
|
|
|
90
92
|
visitERBEnsureNode(node: ERBEnsureNode): void;
|
|
91
93
|
visitERBBeginNode(node: ERBBeginNode): void;
|
|
92
94
|
visitERBUnlessNode(node: ERBUnlessNode): void;
|
|
95
|
+
visitRubyRenderLocalNode(node: RubyRenderLocalNode): void;
|
|
96
|
+
visitERBRenderNode(node: ERBRenderNode): void;
|
|
93
97
|
visitERBYieldNode(node: ERBYieldNode): void;
|
|
94
98
|
visitERBInNode(node: ERBInNode): void;
|
|
95
99
|
}
|
package/package.json
CHANGED
package/src/ast-utils.ts
CHANGED
|
@@ -188,7 +188,7 @@ export function hasStaticAttributeName(attributeNameNode: HTMLAttributeNameNode)
|
|
|
188
188
|
/**
|
|
189
189
|
* Checks if an HTML attribute name node has dynamic content (contains ERB)
|
|
190
190
|
*/
|
|
191
|
-
export function
|
|
191
|
+
export function hasDynamicAttributeNameNode(attributeNameNode: HTMLAttributeNameNode): boolean {
|
|
192
192
|
if (!attributeNameNode.children) {
|
|
193
193
|
return false
|
|
194
194
|
}
|
|
@@ -383,12 +383,11 @@ export function hasAttribute(node: HTMLElementNode | HTMLOpenTagNode | null | un
|
|
|
383
383
|
|
|
384
384
|
/**
|
|
385
385
|
* Checks if an attribute has a dynamic (ERB-containing) name.
|
|
386
|
-
* Accepts an HTMLAttributeNode (wraps the core HTMLAttributeNameNode-level check).
|
|
387
386
|
*/
|
|
388
|
-
export function
|
|
387
|
+
export function hasDynamicAttributeName(attributeNode: HTMLAttributeNode): boolean {
|
|
389
388
|
if (!isHTMLAttributeNameNode(attributeNode.name)) return false
|
|
390
389
|
|
|
391
|
-
return
|
|
390
|
+
return hasDynamicAttributeNameNode(attributeNode.name)
|
|
392
391
|
}
|
|
393
392
|
|
|
394
393
|
/**
|
package/src/diagnostic.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Location, SerializedLocation } from "./location.js"
|
|
2
2
|
|
|
3
3
|
export type DiagnosticSeverity = "error" | "warning" | "info" | "hint"
|
|
4
|
+
export type DiagnosticTag = "unnecessary" | "deprecated"
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Base interface for all diagnostic information in Herb tooling.
|
|
@@ -32,6 +33,11 @@ export interface Diagnostic {
|
|
|
32
33
|
* Optional source that generated this diagnostic (e.g., "parser", "linter", "lexer")
|
|
33
34
|
*/
|
|
34
35
|
source?: string
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Optional diagnostic tags for additional metadata (e.g., "unnecessary", "deprecated")
|
|
39
|
+
*/
|
|
40
|
+
tags?: DiagnosticTag[]
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
/**
|
|
@@ -43,6 +49,7 @@ export interface SerializedDiagnostic {
|
|
|
43
49
|
severity: DiagnosticSeverity
|
|
44
50
|
code?: string
|
|
45
51
|
source?: string
|
|
52
|
+
tags?: DiagnosticTag[]
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
export type MonacoSeverity = "error" | "warning" | "info"
|