Skip to content

Commit 0b03387

Browse files
committed
Cleanup
1 parent 2ba22c3 commit 0b03387

File tree

5 files changed

+145
-70
lines changed

5 files changed

+145
-70
lines changed
Lines changed: 110 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,50 @@
11
import { FoldingRange, FoldingRangeKind } from "vscode-languageserver/node"
2+
import { TextDocument } from "vscode-languageserver-textdocument"
3+
24
import { Visitor } from "@herb-tools/core"
5+
import { ParserService } from "./parser_service"
6+
7+
import { isERBIfNode } from "@herb-tools/core"
8+
import { lspLine } from "./range_utils"
39

410
import type {
511
Node,
612
ERBNode,
13+
ERBContentNode,
714
HTMLElementNode,
815
HTMLOpenTagNode,
916
HTMLAttributeValueNode,
1017
HTMLCommentNode,
18+
HTMLConditionalElementNode,
19+
CDATANode,
1120
ERBIfNode,
12-
DocumentNode,
21+
ERBUnlessNode,
22+
ERBCaseNode,
23+
ERBCaseMatchNode,
24+
ERBBeginNode,
25+
SerializedPosition,
1326
} from "@herb-tools/core"
1427

1528
export class FoldingRangeService {
16-
getFoldingRanges(document: DocumentNode): FoldingRange[] {
29+
private parserService: ParserService
30+
31+
constructor(parserService: ParserService) {
32+
this.parserService = parserService
33+
}
34+
35+
getFoldingRanges(textDocument: TextDocument): FoldingRange[] {
36+
const parseResult = this.parserService.parseDocument(textDocument)
1737
const collector = new FoldingRangeCollector()
18-
collector.visit(document)
38+
39+
collector.visit(parseResult.document)
40+
1941
return collector.ranges
2042
}
2143
}
2244

23-
class FoldingRangeCollector extends Visitor {
24-
ranges: FoldingRange[] = []
45+
export class FoldingRangeCollector extends Visitor {
46+
public ranges: FoldingRange[] = []
47+
private processedIfNodes: Set<ERBIfNode> = new Set()
2548

2649
visitHTMLElementNode(node: HTMLElementNode): void {
2750
this.addRangeForNode(node, node.body)
@@ -34,9 +57,7 @@ class FoldingRangeCollector extends Visitor {
3457
}
3558

3659
visitHTMLCommentNode(node: HTMLCommentNode): void {
37-
const startLine = this.toZeroBased(node.location.start.line)
38-
const endLine = this.toZeroBased(node.location.end.line)
39-
this.addRange(startLine, endLine, FoldingRangeKind.Comment)
60+
this.addRange(node.location.start, node.location.end, FoldingRangeKind.Comment)
4061
this.visitChildNodes(node)
4162
}
4263

@@ -45,43 +66,107 @@ class FoldingRangeCollector extends Visitor {
4566
this.visitChildNodes(node)
4667
}
4768

69+
visitCDATANode(node: CDATANode): void {
70+
this.addRange(node.location.start, node.location.end)
71+
this.visitChildNodes(node)
72+
}
73+
74+
visitHTMLConditionalElementNode(node: HTMLConditionalElementNode): void {
75+
this.addRange(node.location.start, node.location.end)
76+
this.visitChildNodes(node)
77+
}
78+
4879
visitERBNode(node: ERBNode): void {
49-
const startLine = this.toZeroBased(node.location.start.line)
50-
const endLine = this.toZeroBased(node.location.end.line)
51-
this.addRange(startLine, endLine)
80+
this.addRange(node.location.start, node.location.end)
81+
}
82+
83+
visitERBContentNode(node: ERBContentNode): void {
84+
this.addRange(node.location.start, node.location.end)
85+
this.visitChildNodes(node)
5286
}
5387

5488
visitERBIfNode(node: ERBIfNode): void {
55-
const startLine = this.toZeroBased(node.location.start.line)
56-
const endLine = this.toZeroBased(node.location.end.line)
57-
this.addRange(startLine, endLine)
89+
if (this.processedIfNodes.has(node)) {
90+
this.visitChildNodes(node)
91+
return
92+
}
93+
94+
this.markIfChainAsProcessed(node)
95+
this.addRange(node.location.start, node.location.end)
5896

5997
if (node.statements.length > 0) {
6098
const firstStatement = node.statements[0]
6199
const lastStatement = node.statements[node.statements.length - 1]
62-
const statementsStartLine = this.toZeroBased(firstStatement.location.start.line)
63-
const statementsEndLine = this.toZeroBased(lastStatement.location.end.line)
64-
this.addRange(statementsStartLine, statementsEndLine)
100+
101+
this.addRange(firstStatement.location.start, lastStatement.location.end)
65102
}
66103

104+
let current: Node | null = node.subsequent
105+
106+
while (current) {
107+
if (isERBIfNode(current)) {
108+
if (current.statements.length > 0) {
109+
const firstStatement = current.statements[0]
110+
const lastStatement = current.statements[current.statements.length - 1]
111+
this.addRange(firstStatement.location.start, lastStatement.location.end)
112+
}
113+
114+
current = current.subsequent
115+
} else {
116+
break
117+
}
118+
}
119+
120+
this.visitChildNodes(node)
121+
}
122+
123+
visitERBUnlessNode(node: ERBUnlessNode): void {
124+
this.addRange(node.location.start, node.location.end)
67125
this.visitChildNodes(node)
68126
}
69127

70-
private addRange(startLine: number, endLine: number, kind?: FoldingRangeKind): void {
128+
visitERBCaseNode(node: ERBCaseNode): void {
129+
this.addRange(node.location.start, node.location.end)
130+
this.visitChildNodes(node)
131+
}
132+
133+
visitERBCaseMatchNode(node: ERBCaseMatchNode): void {
134+
this.addRange(node.location.start, node.location.end)
135+
this.visitChildNodes(node)
136+
}
137+
138+
visitERBBeginNode(node: ERBBeginNode): void {
139+
this.addRange(node.location.start, node.location.end)
140+
this.visitChildNodes(node)
141+
}
142+
143+
private markIfChainAsProcessed(node: ERBIfNode): void {
144+
this.processedIfNodes.add(node)
145+
146+
let current: Node | null = node.subsequent
147+
148+
while (current) {
149+
if (isERBIfNode(current)) {
150+
this.processedIfNodes.add(current)
151+
current = current.subsequent
152+
} else {
153+
break
154+
}
155+
}
156+
}
157+
158+
private addRange(start: SerializedPosition, end: SerializedPosition, kind?: FoldingRangeKind): void {
159+
const startLine = lspLine(start)
160+
const endLine = lspLine(end)
161+
71162
if (endLine > startLine) {
72163
this.ranges.push({ startLine, endLine, kind })
73164
}
74165
}
75166

76167
private addRangeForNode(node: Node, children: Node[]) {
77168
if (children.length > 0) {
78-
const startLine = this.toZeroBased(node.location.start.line)
79-
const endLine = this.toZeroBased(node.location.end.line)
80-
this.addRange(startLine, endLine)
169+
this.addRange(node.location.start, node.location.end)
81170
}
82171
}
83-
84-
private toZeroBased(line: number): number {
85-
return line - 1
86-
}
87172
}

javascript/packages/language-server/src/range_utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ export function lspPosition(herbPosition: SerializedPosition): Position {
66
return Position.create(herbPosition.line - 1, herbPosition.column)
77
}
88

9+
export function lspLine(herbPosition: SerializedPosition): number {
10+
return herbPosition.line - 1
11+
}
12+
913
export function lspRangeFromLocation(herbLocation: SerializedLocation): Range {
1014
return Range.create(lspPosition(herbLocation.start), lspPosition(herbLocation.end))
1115
}

javascript/packages/language-server/src/server.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,7 @@ export class Server {
193193

194194
if (!document) return []
195195

196-
const parseResult = this.service.parserService.parseDocument(document)
197-
198-
return this.service.foldingRangeService.getFoldingRanges(parseResult.document)
196+
return this.service.foldingRangeService.getFoldingRanges(document)
199197
})
200198
}
201199

javascript/packages/language-server/src/service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class Service {
4848
this.codeActionService = new CodeActionService(this.project, this.config)
4949
this.diagnostics = new Diagnostics(this.connection, this.documentService, this.parserService, this.linterService, this.configService)
5050
this.documentSaveService = new DocumentSaveService(this.connection, this.settings, this.autofixService, this.formattingService)
51-
this.foldingRangeService = new FoldingRangeService()
51+
this.foldingRangeService = new FoldingRangeService(this.parserService)
5252
this.documentHighlightService = new DocumentHighlightService(this.parserService)
5353

5454
if (params.initializationOptions) {

0 commit comments

Comments
 (0)