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; | |
8 | |
9 import 'package:front_end/src/fasta/parser.dart' show ErrorKind, Listener; | 7 import 'package:front_end/src/fasta/parser.dart' show ErrorKind, Listener; |
10 | 8 |
11 import 'package:front_end/src/fasta/scanner.dart' show BeginGroupToken, Token; | 9 import 'package:front_end/src/fasta/scanner.dart' show BeginGroupToken, Token; |
12 | 10 |
13 import 'package:kernel/ast.dart' show AsyncMarker; | 11 import 'package:kernel/ast.dart' show AsyncMarker; |
14 | 12 |
15 import '../errors.dart' show inputError, internalError; | 13 import '../errors.dart' show inputError, internalError; |
16 | 14 |
17 import '../quote.dart' show unescapeString; | 15 import '../quote.dart' show unescapeString; |
18 | 16 |
(...skipping 17 matching lines...) Expand all Loading... |
36 Modifiers, | 34 Modifiers, |
37 SwitchScope, | 35 SwitchScope, |
38 Type, | 36 Type, |
39 TypeArguments, | 37 TypeArguments, |
40 TypeList, | 38 TypeList, |
41 TypeVariable, | 39 TypeVariable, |
42 TypeVariables, | 40 TypeVariables, |
43 } | 41 } |
44 | 42 |
45 abstract class StackListener extends Listener { | 43 abstract class StackListener extends Listener { |
46 final Queue<Object> stack = new Queue<Object>(); | 44 final Stack stack = new Stack(); |
47 | 45 |
48 Uri get uri; | 46 Uri get uri; |
49 | 47 |
50 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart | 48 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart |
51 // and ast_builder.dart. | 49 // and ast_builder.dart. |
52 void finishFunction( | 50 void finishFunction( |
53 covariant formals, AsyncMarker asyncModifier, covariant body) { | 51 covariant formals, AsyncMarker asyncModifier, covariant body) { |
54 return internalError("Unsupported operation"); | 52 return internalError("Unsupported operation"); |
55 } | 53 } |
56 | 54 |
57 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart | 55 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart |
58 // and ast_builder.dart. | 56 // and ast_builder.dart. |
59 void exitLocalScope() => internalError("Unsupported operation"); | 57 void exitLocalScope() => internalError("Unsupported operation"); |
60 | 58 |
61 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart | 59 // TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart |
62 // and ast_builder.dart. | 60 // and ast_builder.dart. |
63 void prepareInitializers() => internalError("Unsupported operation"); | 61 void prepareInitializers() => internalError("Unsupported operation"); |
64 | 62 |
65 void push(Object node) { | 63 void push(Object node) { |
66 if (node == null) internalError("null not allowed."); | 64 if (node == null) internalError("null not allowed."); |
67 stack.addLast(node); | 65 stack.push(node); |
68 } | 66 } |
69 | 67 |
70 Object peek() { | 68 Object peek() => stack.last; |
71 Object node = stack.last; | |
72 return node is NullValue ? null : node; | |
73 } | |
74 | 69 |
75 Object pop() { | 70 Object pop() => stack.pop(); |
76 Object node = stack.removeLast(); | |
77 return node is NullValue ? null : node; | |
78 } | |
79 | 71 |
80 Object popIfNotNull(Object value) { | 72 Object popIfNotNull(Object value) { |
81 return value == null ? null : pop(); | 73 return value == null ? null : pop(); |
82 } | 74 } |
83 | 75 |
84 List popList(int n) { | 76 List popList(int n) { |
85 if (n == 0) return null; | 77 if (n == 0) return null; |
86 List list = new List.filled(n, null, growable: true); | 78 return stack.popList(n); |
87 for (int i = n - 1; i >= 0; i--) { | |
88 list[i] = pop(); | |
89 } | |
90 return list; | |
91 } | 79 } |
92 | 80 |
93 void debugEvent(String name) { | 81 void debugEvent(String name) { |
94 // printEvent(name); | 82 // printEvent(name); |
95 } | 83 } |
96 | 84 |
97 void printEvent(String name) { | 85 void printEvent(String name) { |
98 for (Object o in stack) { | 86 for (Object o in stack.values) { |
99 String s = " $o"; | 87 String s = " $o"; |
100 int index = s.indexOf("\n"); | 88 int index = s.indexOf("\n"); |
101 if (index != -1) { | 89 if (index != -1) { |
102 s = s.substring(0, index) + "..."; | 90 s = s.substring(0, index) + "..."; |
103 } | 91 } |
104 print(s); | 92 print(s); |
105 } | 93 } |
106 print(name); | 94 print(name); |
107 } | 95 } |
108 | 96 |
109 @override | 97 @override |
110 void logEvent(String name) { | 98 void logEvent(String name) { |
111 internalError("Unhandled event: $name in $runtimeType $uri:\n" | 99 internalError("Unhandled event: $name in $runtimeType $uri:\n" |
112 " ${stack.join('\n ')}"); | 100 " ${stack.values.join('\n ')}"); |
113 } | 101 } |
114 | 102 |
115 @override | 103 @override |
116 void handleIdentifier(Token token) { | 104 void handleIdentifier(Token token) { |
117 debugEvent("handleIdentifier"); | 105 debugEvent("handleIdentifier"); |
118 push(token.value); | 106 push(token.value); |
119 } | 107 } |
120 | 108 |
121 @override | 109 @override |
122 void endInitializer(Token token) { | 110 void endInitializer(Token token) { |
123 debugEvent("Initializer"); | 111 debugEvent("Initializer"); |
124 } | 112 } |
125 | 113 |
126 void checkEmpty(int charOffset) { | 114 void checkEmpty(int charOffset) { |
127 if (stack.isNotEmpty) { | 115 if (stack.isNotEmpty) { |
128 internalError("${runtimeType}: Stack not empty:\n" | 116 internalError("${runtimeType}: Stack not empty:\n" |
129 " ${stack.join('\n ')}", uri, charOffset); | 117 " ${stack.values.join('\n ')}", uri, charOffset); |
130 } | 118 } |
131 if (recoverableErrors.isNotEmpty) { | 119 if (recoverableErrors.isNotEmpty) { |
132 // TODO(ahe): Handle recoverable errors better. | 120 // TODO(ahe): Handle recoverable errors better. |
133 inputError(uri, recoverableErrors.first.beginOffset, recoverableErrors); | 121 inputError(uri, recoverableErrors.first.beginOffset, recoverableErrors); |
134 } | 122 } |
135 } | 123 } |
136 | 124 |
137 @override | 125 @override |
138 void endTopLevelDeclaration(Token token) { | 126 void endTopLevelDeclaration(Token token) { |
139 debugEvent("TopLevelDeclaration"); | 127 debugEvent("TopLevelDeclaration"); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 } | 221 } |
234 | 222 |
235 void nit(String message, [int charOffset = -1]) { | 223 void nit(String message, [int charOffset = -1]) { |
236 messages.nit(uri, charOffset, message); | 224 messages.nit(uri, charOffset, message); |
237 } | 225 } |
238 | 226 |
239 void warning(String message, [int charOffset = -1]) { | 227 void warning(String message, [int charOffset = -1]) { |
240 messages.warning(uri, charOffset, message); | 228 messages.warning(uri, charOffset, message); |
241 } | 229 } |
242 } | 230 } |
| 231 |
| 232 class Stack { |
| 233 List array = new List(8); |
| 234 int arrayLength = 0; |
| 235 |
| 236 bool get isNotEmpty => arrayLength > 0; |
| 237 |
| 238 int get length => arrayLength; |
| 239 |
| 240 Object get last { |
| 241 final value = array[arrayLength - 1]; |
| 242 return value is NullValue ? null : value; |
| 243 } |
| 244 |
| 245 void push(Object value) { |
| 246 array[arrayLength++] = value; |
| 247 if (array.length == arrayLength) { |
| 248 _grow(); |
| 249 } |
| 250 } |
| 251 |
| 252 Object pop() { |
| 253 assert(arrayLength > 0); |
| 254 final Object value = array[--arrayLength]; |
| 255 array[arrayLength] = null; |
| 256 return value is NullValue ? null : value; |
| 257 } |
| 258 |
| 259 List<Object> popList(int count) { |
| 260 assert(arrayLength >= count); |
| 261 |
| 262 final table = array; |
| 263 final length = arrayLength; |
| 264 |
| 265 final tailList = new List<Object>.filled(count, null, growable: true); |
| 266 final startIndex = length - count; |
| 267 for (int i = 0; i < count; i++) { |
| 268 final value = table[startIndex + i]; |
| 269 tailList[i] = value is NullValue ? null : value; |
| 270 } |
| 271 arrayLength -= count; |
| 272 |
| 273 return tailList; |
| 274 } |
| 275 |
| 276 List<Object> get values { |
| 277 final List<Object> list = new List<Object>(arrayLength); |
| 278 list.setRange(0, arrayLength, array); |
| 279 return list; |
| 280 } |
| 281 |
| 282 void _grow() { |
| 283 final List<Object> newTable = new List<Object>(array.length * 2); |
| 284 newTable.setRange(0, array.length, array, 0); |
| 285 array = newTable; |
| 286 } |
| 287 } |
OLD | NEW |