OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import 'package:source_span/source_span.dart'; | |
6 | |
7 import 'visitor.dart'; | |
8 | |
9 /// The superclass of nodes in the platform selector abstract syntax tree. | |
10 abstract class Node { | |
11 /// The span indicating where this node came from. | |
12 /// | |
13 /// This is a [FileSpan] because the nodes are parsed from a single continuous | |
14 /// string, but the string itself isn't actually a file. It might come from a | |
15 /// statically-parsed annotation or from a parameter. | |
16 /// | |
17 /// This may be `null` for nodes without source information. | |
18 FileSpan get span; | |
19 | |
20 /// Calls the appropriate [Visitor] method on [this] and returns the result. | |
21 accept(Visitor visitor); | |
22 } | |
23 | |
24 /// A single variable. | |
25 class VariableNode implements Node { | |
26 final FileSpan span; | |
27 | |
28 /// The variable name. | |
29 final String name; | |
30 | |
31 VariableNode(this.name, [this.span]); | |
32 | |
33 accept(Visitor visitor) => visitor.visitVariable(this); | |
34 | |
35 String toString() => name; | |
36 } | |
37 | |
38 /// A negation expression. | |
39 class NotNode implements Node { | |
40 final FileSpan span; | |
41 | |
42 /// The expression being negated. | |
43 final Node child; | |
44 | |
45 NotNode(this.child, [this.span]); | |
46 | |
47 accept(Visitor visitor) => visitor.visitNot(this); | |
48 | |
49 String toString() => child is VariableNode || child is NotNode | |
50 ? "!$child" | |
51 : "!($child)"; | |
52 } | |
53 | |
54 /// An or expression. | |
55 class OrNode implements Node { | |
56 FileSpan get span => _expandSafe(left.span, right.span); | |
57 | |
58 /// The left-hand branch of the expression. | |
59 final Node left; | |
60 | |
61 /// The right-hand branch of the expression. | |
62 final Node right; | |
63 | |
64 OrNode(this.left, this.right); | |
65 | |
66 accept(Visitor visitor) => visitor.visitOr(this); | |
67 | |
68 String toString() { | |
69 var string1 = left is AndNode || left is ConditionalNode | |
70 ? "($left)" | |
71 : left; | |
72 var string2 = right is AndNode || right is ConditionalNode | |
73 ? "($right)" | |
74 : right; | |
75 | |
76 return "$string1 || $string2"; | |
77 } | |
78 } | |
79 | |
80 /// An and expression. | |
81 class AndNode implements Node { | |
82 FileSpan get span => _expandSafe(left.span, right.span); | |
83 | |
84 /// The left-hand branch of the expression. | |
85 final Node left; | |
86 | |
87 /// The right-hand branch of the expression. | |
88 final Node right; | |
89 | |
90 AndNode(this.left, this.right); | |
91 | |
92 accept(Visitor visitor) => visitor.visitAnd(this); | |
93 | |
94 String toString() { | |
95 var string1 = left is OrNode || left is ConditionalNode | |
96 ? "($left)" | |
97 : left; | |
98 var string2 = right is OrNode || right is ConditionalNode | |
99 ? "($right)" | |
100 : right; | |
101 | |
102 return "$string1 && $string2"; | |
103 } | |
104 } | |
105 | |
106 /// A ternary conditional expression. | |
107 class ConditionalNode implements Node { | |
108 FileSpan get span => _expandSafe(condition.span, whenFalse.span); | |
109 | |
110 /// The condition expression to check. | |
111 final Node condition; | |
112 | |
113 /// The branch to run if the condition is true. | |
114 final Node whenTrue; | |
115 | |
116 /// The branch to run if the condition is false. | |
117 final Node whenFalse; | |
118 | |
119 ConditionalNode(this.condition, this.whenTrue, this.whenFalse); | |
120 | |
121 accept(Visitor visitor) => visitor.visitConditional(this); | |
122 | |
123 String toString() { | |
124 var conditionString = | |
125 condition is ConditionalNode ? "($condition)" : condition; | |
126 var trueString = whenTrue is ConditionalNode ? "($whenTrue)" : whenTrue; | |
127 return "$conditionString ? $trueString : $whenFalse"; | |
128 } | |
129 } | |
130 | |
131 /// Like [FileSpan.expand], except if [start] and [end] are `null` or from | |
132 /// different files it returns `null` rather than throwing an error. | |
133 FileSpan _expandSafe(FileSpan start, FileSpan end) { | |
134 if (start == null || end == null) return null; | |
135 if (start.file != end.file) return null; | |
136 return start.expand(end); | |
137 } | |
OLD | NEW |