| 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 |