-
Notifications
You must be signed in to change notification settings - Fork 1
/
ast.dart
63 lines (50 loc) · 1.8 KB
/
ast.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// Base class for any AST item. Roughly corresponds to Node in the DOM. Will
/// be either an Element or Text.
interface Node {
void accept(NodeVisitor visitor);
}
/// A named tag that can contain other nodes.
class Element implements Node {
final String tag;
final List<Node> children;
final Map<String, String> attributes;
Element(this.tag, this.children)
: attributes = <String>{};
Element.empty(this.tag)
: children = null,
attributes = <String>{};
Element.tag(this.tag)
: children = [],
attributes = <String>{};
Element.text(this.tag, String text)
: children = [new Text(text)],
attributes = <String>{};
bool get isEmpty() => children == null;
void accept(NodeVisitor visitor) {
if (visitor.visitElementBefore(this)) {
for (final child in children) child.accept(visitor);
visitor.visitElementAfter(this);
}
}
}
/// A plain text element.
class Text implements Node {
final String text;
Text(this.text);
void accept(NodeVisitor visitor) => visitor.visitText(this);
}
/// Visitor pattern for the AST. Renderers or other AST transformers should
/// implement this.
interface NodeVisitor {
/// Called when a Text node has been reached.
void visitText(Text text);
/// Called when an Element has been reached, before its children have been
/// visited. Return `false` to skip its children.
bool visitElementBefore(Element element);
/// Called when an Element has been reached, after its children have been
/// visited. Will not be called if [visitElementBefore] returns `false`.
void visitElementAfter(Element element);
}