OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library fasta.stack_listener; | 5 library fasta.stack_listener; |
6 | 6 |
7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
8 | 8 |
9 import 'package:front_end/src/fasta/parser.dart' show ErrorKind, Listener; | 9 import 'package:front_end/src/fasta/parser.dart' show ErrorKind, Listener; |
10 | 10 |
(...skipping 25 matching lines...) Expand all Loading... | |
36 Modifiers, | 36 Modifiers, |
37 SwitchScope, | 37 SwitchScope, |
38 Type, | 38 Type, |
39 TypeArguments, | 39 TypeArguments, |
40 TypeList, | 40 TypeList, |
41 TypeVariable, | 41 TypeVariable, |
42 TypeVariables, | 42 TypeVariables, |
43 } | 43 } |
44 | 44 |
45 abstract class StackListener extends Listener { | 45 abstract class StackListener extends Listener { |
46 final Queue<Object> stack = new Queue<Object>(); | 46 final _Stack<Object> stack = new _Stack<Object>(); |
47 | 47 |
48 Uri get uri; | 48 Uri get uri; |
49 | 49 |
50 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart | 50 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart |
51 // and ast_builder.dart. | 51 // and ast_builder.dart. |
52 void finishFunction( | 52 void finishFunction( |
53 covariant formals, AsyncMarker asyncModifier, covariant body) { | 53 covariant formals, AsyncMarker asyncModifier, covariant body) { |
54 return internalError("Unsupported operation"); | 54 return internalError("Unsupported operation"); |
55 } | 55 } |
56 | 56 |
57 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart | 57 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart |
58 // and ast_builder.dart. | 58 // and ast_builder.dart. |
59 void exitLocalScope() => internalError("Unsupported operation"); | 59 void exitLocalScope() => internalError("Unsupported operation"); |
60 | 60 |
61 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart | 61 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart |
62 // and ast_builder.dart. | 62 // and ast_builder.dart. |
63 void prepareInitializers() => internalError("Unsupported operation"); | 63 void prepareInitializers() => internalError("Unsupported operation"); |
64 | 64 |
65 void push(Object node) { | 65 void push(Object node) { |
66 if (node == null) internalError("null not allowed."); | 66 if (node == null) internalError("null not allowed."); |
67 stack.addLast(node); | 67 stack.push(node); |
68 } | 68 } |
69 | 69 |
70 Object peek() { | 70 Object peek() => stack.last; |
71 Object node = stack.last; | |
72 return node is NullValue ? null : node; | |
73 } | |
74 | 71 |
75 Object pop() { | 72 Object pop() => stack.pop(); |
76 Object node = stack.removeLast(); | |
77 return node is NullValue ? null : node; | |
78 } | |
79 | 73 |
80 Object popIfNotNull(Object value) { | 74 Object popIfNotNull(Object value) { |
81 return value == null ? null : pop(); | 75 return value == null ? null : pop(); |
82 } | 76 } |
83 | 77 |
84 List popList(int n) { | 78 List popList(int n) { |
85 if (n == 0) return null; | 79 if (n == 0) return null; |
86 List list = new List.filled(n, null, growable: true); | 80 return stack.popList(n); |
87 for (int i = n - 1; i >= 0; i--) { | |
88 list[i] = pop(); | |
89 } | |
90 return list; | |
91 } | 81 } |
kustermann
2017/02/21 13:29:09
It's more efficient to implement stack.popList() d
| |
92 | 82 |
93 void debugEvent(String name) { | 83 void debugEvent(String name) { |
94 // printEvent(name); | 84 // printEvent(name); |
95 } | 85 } |
96 | 86 |
97 void printEvent(String name) { | 87 void printEvent(String name) { |
98 for (Object o in stack) { | 88 for (Object o in stack.values) { |
99 String s = " $o"; | 89 String s = " $o"; |
100 int index = s.indexOf("\n"); | 90 int index = s.indexOf("\n"); |
101 if (index != -1) { | 91 if (index != -1) { |
102 s = s.substring(0, index) + "..."; | 92 s = s.substring(0, index) + "..."; |
103 } | 93 } |
104 print(s); | 94 print(s); |
105 } | 95 } |
106 print(name); | 96 print(name); |
107 } | 97 } |
108 | 98 |
109 @override | 99 @override |
110 void logEvent(String name) { | 100 void logEvent(String name) { |
111 internalError("Unhandled event: $name in $runtimeType $uri:\n" | 101 internalError("Unhandled event: $name in $runtimeType $uri:\n" |
112 " ${stack.join('\n ')}"); | 102 " ${stack.values.join('\n ')}"); |
113 } | 103 } |
114 | 104 |
115 @override | 105 @override |
116 void handleIdentifier(Token token) { | 106 void handleIdentifier(Token token) { |
117 debugEvent("handleIdentifier"); | 107 debugEvent("handleIdentifier"); |
118 push(token.value); | 108 push(token.value); |
119 } | 109 } |
120 | 110 |
121 @override | 111 @override |
122 void endInitializer(Token token) { | 112 void endInitializer(Token token) { |
123 debugEvent("Initializer"); | 113 debugEvent("Initializer"); |
124 } | 114 } |
125 | 115 |
126 void checkEmpty(int charOffset) { | 116 void checkEmpty(int charOffset) { |
127 if (stack.isNotEmpty) { | 117 if (stack.isNotEmpty) { |
128 internalError("${runtimeType}: Stack not empty:\n" | 118 internalError("${runtimeType}: Stack not empty:\n" |
129 " ${stack.join('\n ')}", uri, charOffset); | 119 " ${stack.values.join('\n ')}", uri, charOffset); |
130 } | 120 } |
131 if (recoverableErrors.isNotEmpty) { | 121 if (recoverableErrors.isNotEmpty) { |
132 // TODO(ahe): Handle recoverable errors better. | 122 // TODO(ahe): Handle recoverable errors better. |
133 inputError(uri, recoverableErrors.first.beginOffset, recoverableErrors); | 123 inputError(uri, recoverableErrors.first.beginOffset, recoverableErrors); |
134 } | 124 } |
135 } | 125 } |
136 | 126 |
137 @override | 127 @override |
138 void endTopLevelDeclaration(Token token) { | 128 void endTopLevelDeclaration(Token token) { |
139 debugEvent("TopLevelDeclaration"); | 129 debugEvent("TopLevelDeclaration"); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
233 } | 223 } |
234 | 224 |
235 void nit(String message, [int charOffset = -1]) { | 225 void nit(String message, [int charOffset = -1]) { |
236 messages.nit(uri, charOffset, message); | 226 messages.nit(uri, charOffset, message); |
237 } | 227 } |
238 | 228 |
239 void warning(String message, [int charOffset = -1]) { | 229 void warning(String message, [int charOffset = -1]) { |
240 messages.warning(uri, charOffset, message); | 230 messages.warning(uri, charOffset, message); |
241 } | 231 } |
242 } | 232 } |
233 | |
234 class _Stack<E> { | |
ahe
2017/02/21 14:24:34
Please don't use privacy.
ahe
2017/02/21 14:24:34
I think you don't need the type variable. It shoul
kustermann
2017/02/22 13:59:37
Done.
kustermann
2017/02/22 13:59:37
Done.
| |
235 List<E> _table = new List<E>(8); | |
ahe
2017/02/21 14:24:34
This type annotation isn't correct as NullValue is
kustermann
2017/02/22 13:59:37
Thanks.
| |
236 int _length = 0; | |
237 | |
238 bool get isNotEmpty => _length > 0; | |
239 | |
240 int get length => _length; | |
241 | |
242 E get last { | |
243 final value = _table[_length - 1]; | |
244 return value is NullValue ? null : value; | |
245 } | |
246 | |
247 void push(E value) { | |
248 _table[_length++] = value; | |
249 if (_table.length == _length) { | |
250 _grow(); | |
251 } | |
252 } | |
253 | |
254 E pop() { | |
255 assert(_length > 0); | |
256 final E value = _table[--_length]; | |
257 _table[_length] = null; | |
258 return value is NullValue ? null : value; | |
259 } | |
260 | |
261 List<E> popList(int count) { | |
262 assert(_length >= count); | |
263 | |
264 final table = _table; | |
265 final length = _length; | |
266 | |
267 final tailList = new List<E>.filled(count, null, growable: true); | |
268 final startIndex = length - count; | |
269 for (int i = 0; i < count; i++) { | |
270 final value = table[startIndex + i]; | |
271 tailList[i] = value is NullValue ? null : value; | |
272 } | |
273 _length -= count; | |
274 | |
275 return tailList; | |
276 } | |
277 | |
278 List<E> get values { | |
279 final List<E> list = new List<E>(_length); | |
280 list.setRange(0, _length, _table); | |
281 return list; | |
282 } | |
283 | |
284 void _grow() { | |
285 final List<E> newTable = new List<E>(_table.length * 2); | |
286 newTable.setRange(0, _table.length, _table, 0); | |
287 _table = newTable; | |
288 } | |
289 } | |
OLD | NEW |