| 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 serialization.summarize_const_expr; | 5 library serialization.summarize_const_expr; |
| 6 | 6 |
| 7 import 'package:analyzer/src/generated/ast.dart'; | 7 import 'package:analyzer/src/generated/ast.dart'; |
| 8 import 'package:analyzer/src/generated/scanner.dart'; | 8 import 'package:analyzer/src/generated/scanner.dart'; |
| 9 import 'package:analyzer/src/summary/format.dart'; | 9 import 'package:analyzer/src/summary/format.dart'; |
| 10 import 'package:analyzer/src/summary/idl.dart'; | 10 import 'package:analyzer/src/summary/idl.dart'; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 } | 37 } |
| 38 throw new StateError('Unexpected initializer type ${node.runtimeType}'); | 38 throw new StateError('Unexpected initializer type ${node.runtimeType}'); |
| 39 } | 39 } |
| 40 | 40 |
| 41 /** | 41 /** |
| 42 * Instances of this class keep track of intermediate state during | 42 * Instances of this class keep track of intermediate state during |
| 43 * serialization of a single constant [Expression]. | 43 * serialization of a single constant [Expression]. |
| 44 */ | 44 */ |
| 45 abstract class AbstractConstExprSerializer { | 45 abstract class AbstractConstExprSerializer { |
| 46 /** | 46 /** |
| 47 * See [UnlinkedConstBuilder.isInvalid]. |
| 48 */ |
| 49 bool isInvalid = false; |
| 50 |
| 51 /** |
| 47 * See [UnlinkedConstBuilder.operations]. | 52 * See [UnlinkedConstBuilder.operations]. |
| 48 */ | 53 */ |
| 49 final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[]; | 54 final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[]; |
| 50 | 55 |
| 51 /** | 56 /** |
| 52 * See [UnlinkedConstBuilder.ints]. | 57 * See [UnlinkedConstBuilder.ints]. |
| 53 */ | 58 */ |
| 54 final List<int> ints = <int>[]; | 59 final List<int> ints = <int>[]; |
| 55 | 60 |
| 56 /** | 61 /** |
| (...skipping 14 matching lines...) Expand all Loading... |
| 71 /** | 76 /** |
| 72 * Return `true` if a constructor initializer expression is being serialized | 77 * Return `true` if a constructor initializer expression is being serialized |
| 73 * and the given [name] is a constructor parameter reference. | 78 * and the given [name] is a constructor parameter reference. |
| 74 */ | 79 */ |
| 75 bool isConstructorParameterName(String name); | 80 bool isConstructorParameterName(String name); |
| 76 | 81 |
| 77 /** | 82 /** |
| 78 * Serialize the given [expr] expression into this serializer state. | 83 * Serialize the given [expr] expression into this serializer state. |
| 79 */ | 84 */ |
| 80 void serialize(Expression expr) { | 85 void serialize(Expression expr) { |
| 81 if (expr is IntegerLiteral) { | 86 try { |
| 82 _pushInt(expr.value); | 87 _serialize(expr); |
| 83 } else if (expr is DoubleLiteral) { | 88 } on StateError { |
| 84 operations.add(UnlinkedConstOperation.pushDouble); | 89 isInvalid = true; |
| 85 doubles.add(expr.value); | |
| 86 } else if (expr is BooleanLiteral) { | |
| 87 if (expr.value) { | |
| 88 operations.add(UnlinkedConstOperation.pushTrue); | |
| 89 } else { | |
| 90 operations.add(UnlinkedConstOperation.pushFalse); | |
| 91 } | |
| 92 } else if (expr is StringLiteral) { | |
| 93 _serializeString(expr); | |
| 94 } else if (expr is SymbolLiteral) { | |
| 95 strings.add(expr.components.map((token) => token.lexeme).join('.')); | |
| 96 operations.add(UnlinkedConstOperation.makeSymbol); | |
| 97 } else if (expr is NullLiteral) { | |
| 98 operations.add(UnlinkedConstOperation.pushNull); | |
| 99 } else if (expr is Identifier) { | |
| 100 if (expr is SimpleIdentifier && isConstructorParameterName(expr.name)) { | |
| 101 strings.add(expr.name); | |
| 102 operations.add(UnlinkedConstOperation.pushConstructorParameter); | |
| 103 } else { | |
| 104 references.add(serializeIdentifier(expr)); | |
| 105 operations.add(UnlinkedConstOperation.pushReference); | |
| 106 } | |
| 107 } else if (expr is InstanceCreationExpression) { | |
| 108 serializeInstanceCreation( | |
| 109 serializeConstructorName( | |
| 110 expr.constructorName.type, expr.constructorName.name), | |
| 111 expr.argumentList); | |
| 112 } else if (expr is ListLiteral) { | |
| 113 _serializeListLiteral(expr); | |
| 114 } else if (expr is MapLiteral) { | |
| 115 _serializeMapLiteral(expr); | |
| 116 } else if (expr is MethodInvocation) { | |
| 117 String name = expr.methodName.name; | |
| 118 if (name != 'identical') { | |
| 119 throw new _ConstExprSerializationError( | |
| 120 'Only "identity" function invocation is allowed.'); | |
| 121 } | |
| 122 if (expr.argumentList == null || | |
| 123 expr.argumentList.arguments.length != 2) { | |
| 124 throw new _ConstExprSerializationError( | |
| 125 'The function "identity" requires exactly 2 arguments.'); | |
| 126 } | |
| 127 expr.argumentList.arguments.forEach(serialize); | |
| 128 operations.add(UnlinkedConstOperation.identical); | |
| 129 } else if (expr is BinaryExpression) { | |
| 130 _serializeBinaryExpression(expr); | |
| 131 } else if (expr is ConditionalExpression) { | |
| 132 serialize(expr.condition); | |
| 133 serialize(expr.thenExpression); | |
| 134 serialize(expr.elseExpression); | |
| 135 operations.add(UnlinkedConstOperation.conditional); | |
| 136 } else if (expr is PrefixExpression) { | |
| 137 _serializePrefixExpression(expr); | |
| 138 } else if (expr is PropertyAccess) { | |
| 139 if (expr.target is! PrefixedIdentifier && | |
| 140 expr.propertyName.name == 'length') { | |
| 141 serialize(expr.target); | |
| 142 operations.add(UnlinkedConstOperation.length); | |
| 143 } else { | |
| 144 references.add(serializePropertyAccess(expr)); | |
| 145 operations.add(UnlinkedConstOperation.pushReference); | |
| 146 } | |
| 147 } else if (expr is ParenthesizedExpression) { | |
| 148 serialize(expr.expression); | |
| 149 } else { | |
| 150 throw new _ConstExprSerializationError('Unknown expression type: $expr'); | |
| 151 } | 90 } |
| 152 } | 91 } |
| 153 | 92 |
| 154 /** | 93 /** |
| 155 * Serialize the given [annotation] into this serializer state. | 94 * Serialize the given [annotation] into this serializer state. |
| 156 */ | 95 */ |
| 157 void serializeAnnotation(Annotation annotation); | 96 void serializeAnnotation(Annotation annotation); |
| 158 | 97 |
| 159 /** | 98 /** |
| 160 * Return [EntityRefBuilder] that corresponds to the constructor having name | 99 * Return [EntityRefBuilder] that corresponds to the constructor having name |
| 161 * [name] in the class identified by [type]. | 100 * [name] in the class identified by [type]. |
| 162 */ | 101 */ |
| 163 EntityRefBuilder serializeConstructorName( | 102 EntityRefBuilder serializeConstructorName( |
| 164 TypeName type, SimpleIdentifier name); | 103 TypeName type, SimpleIdentifier name); |
| 165 | 104 |
| 166 /** | 105 /** |
| 167 * Return [EntityRefBuilder] that corresponds to the given [identifier]. | 106 * Return [EntityRefBuilder] that corresponds to the given [identifier]. |
| 168 */ | 107 */ |
| 169 EntityRefBuilder serializeIdentifier(Identifier identifier); | 108 EntityRefBuilder serializeIdentifier(Identifier identifier); |
| 170 | 109 |
| 110 void serializeInstanceCreation( |
| 111 EntityRefBuilder constructor, ArgumentList argumentList) { |
| 112 List<Expression> arguments = argumentList.arguments; |
| 113 // Serialize the arguments. |
| 114 List<String> argumentNames = <String>[]; |
| 115 arguments.forEach((arg) { |
| 116 if (arg is NamedExpression) { |
| 117 argumentNames.add(arg.name.label.name); |
| 118 _serialize(arg.expression); |
| 119 } else { |
| 120 _serialize(arg); |
| 121 } |
| 122 }); |
| 123 // Add the op-code and numbers of named and positional arguments. |
| 124 operations.add(UnlinkedConstOperation.invokeConstructor); |
| 125 ints.add(argumentNames.length); |
| 126 strings.addAll(argumentNames); |
| 127 ints.add(arguments.length - argumentNames.length); |
| 128 // Serialize the reference. |
| 129 references.add(constructor); |
| 130 } |
| 131 |
| 171 /** | 132 /** |
| 172 * Return [EntityRefBuilder] that corresponds to the given [access]. | 133 * Return [EntityRefBuilder] that corresponds to the given [access]. |
| 173 */ | 134 */ |
| 174 EntityRefBuilder serializePropertyAccess(PropertyAccess access); | 135 EntityRefBuilder serializePropertyAccess(PropertyAccess access); |
| 175 | 136 |
| 176 /** | 137 /** |
| 177 * Return [EntityRefBuilder] that corresponds to the given [type]. | 138 * Return [EntityRefBuilder] that corresponds to the given [type]. |
| 178 */ | 139 */ |
| 179 EntityRefBuilder serializeType(TypeName type); | 140 EntityRefBuilder serializeType(TypeName type); |
| 180 | 141 |
| 181 /** | 142 /** |
| 182 * Return the [UnlinkedConstBuilder] that corresponds to the state of this | 143 * Return the [UnlinkedConstBuilder] that corresponds to the state of this |
| 183 * serializer. | 144 * serializer. |
| 184 */ | 145 */ |
| 185 UnlinkedConstBuilder toBuilder() { | 146 UnlinkedConstBuilder toBuilder() { |
| 147 if (isInvalid) { |
| 148 return new UnlinkedConstBuilder(isInvalid: true); |
| 149 } |
| 186 return new UnlinkedConstBuilder( | 150 return new UnlinkedConstBuilder( |
| 187 operations: operations, | 151 operations: operations, |
| 188 ints: ints, | 152 ints: ints, |
| 189 doubles: doubles, | 153 doubles: doubles, |
| 190 strings: strings, | 154 strings: strings, |
| 191 references: references); | 155 references: references); |
| 192 } | 156 } |
| 193 | 157 |
| 194 void _pushInt(int value) { | 158 void _pushInt(int value) { |
| 195 assert(value >= 0); | 159 assert(value >= 0); |
| 196 if (value >= (1 << 32)) { | 160 if (value >= (1 << 32)) { |
| 197 int numOfComponents = 0; | 161 int numOfComponents = 0; |
| 198 ints.add(numOfComponents); | 162 ints.add(numOfComponents); |
| 199 void pushComponents(int value) { | 163 void pushComponents(int value) { |
| 200 if (value >= (1 << 32)) { | 164 if (value >= (1 << 32)) { |
| 201 pushComponents(value >> 32); | 165 pushComponents(value >> 32); |
| 202 } | 166 } |
| 203 numOfComponents++; | 167 numOfComponents++; |
| 204 ints.add(value & 0xFFFFFFFF); | 168 ints.add(value & 0xFFFFFFFF); |
| 205 } | 169 } |
| 206 pushComponents(value); | 170 pushComponents(value); |
| 207 ints[ints.length - 1 - numOfComponents] = numOfComponents; | 171 ints[ints.length - 1 - numOfComponents] = numOfComponents; |
| 208 operations.add(UnlinkedConstOperation.pushLongInt); | 172 operations.add(UnlinkedConstOperation.pushLongInt); |
| 209 } else { | 173 } else { |
| 210 operations.add(UnlinkedConstOperation.pushInt); | 174 operations.add(UnlinkedConstOperation.pushInt); |
| 211 ints.add(value); | 175 ints.add(value); |
| 212 } | 176 } |
| 213 } | 177 } |
| 214 | 178 |
| 179 /** |
| 180 * Serialize the given [expr] expression into this serializer state. |
| 181 */ |
| 182 void _serialize(Expression expr) { |
| 183 if (expr is IntegerLiteral) { |
| 184 _pushInt(expr.value); |
| 185 } else if (expr is DoubleLiteral) { |
| 186 operations.add(UnlinkedConstOperation.pushDouble); |
| 187 doubles.add(expr.value); |
| 188 } else if (expr is BooleanLiteral) { |
| 189 if (expr.value) { |
| 190 operations.add(UnlinkedConstOperation.pushTrue); |
| 191 } else { |
| 192 operations.add(UnlinkedConstOperation.pushFalse); |
| 193 } |
| 194 } else if (expr is StringLiteral) { |
| 195 _serializeString(expr); |
| 196 } else if (expr is SymbolLiteral) { |
| 197 strings.add(expr.components.map((token) => token.lexeme).join('.')); |
| 198 operations.add(UnlinkedConstOperation.makeSymbol); |
| 199 } else if (expr is NullLiteral) { |
| 200 operations.add(UnlinkedConstOperation.pushNull); |
| 201 } else if (expr is Identifier) { |
| 202 if (expr is SimpleIdentifier && isConstructorParameterName(expr.name)) { |
| 203 strings.add(expr.name); |
| 204 operations.add(UnlinkedConstOperation.pushConstructorParameter); |
| 205 } else { |
| 206 references.add(serializeIdentifier(expr)); |
| 207 operations.add(UnlinkedConstOperation.pushReference); |
| 208 } |
| 209 } else if (expr is InstanceCreationExpression) { |
| 210 serializeInstanceCreation( |
| 211 serializeConstructorName( |
| 212 expr.constructorName.type, expr.constructorName.name), |
| 213 expr.argumentList); |
| 214 } else if (expr is ListLiteral) { |
| 215 _serializeListLiteral(expr); |
| 216 } else if (expr is MapLiteral) { |
| 217 _serializeMapLiteral(expr); |
| 218 } else if (expr is MethodInvocation) { |
| 219 String name = expr.methodName.name; |
| 220 if (name != 'identical') { |
| 221 throw new StateError('Only "identity" function invocation is allowed.'); |
| 222 } |
| 223 if (expr.argumentList == null || |
| 224 expr.argumentList.arguments.length != 2) { |
| 225 throw new StateError( |
| 226 'The function "identity" requires exactly 2 arguments.'); |
| 227 } |
| 228 expr.argumentList.arguments.forEach(_serialize); |
| 229 operations.add(UnlinkedConstOperation.identical); |
| 230 } else if (expr is BinaryExpression) { |
| 231 _serializeBinaryExpression(expr); |
| 232 } else if (expr is ConditionalExpression) { |
| 233 _serialize(expr.condition); |
| 234 _serialize(expr.thenExpression); |
| 235 _serialize(expr.elseExpression); |
| 236 operations.add(UnlinkedConstOperation.conditional); |
| 237 } else if (expr is PrefixExpression) { |
| 238 _serializePrefixExpression(expr); |
| 239 } else if (expr is PropertyAccess) { |
| 240 if (expr.target is! PrefixedIdentifier && |
| 241 expr.propertyName.name == 'length') { |
| 242 _serialize(expr.target); |
| 243 operations.add(UnlinkedConstOperation.length); |
| 244 } else { |
| 245 references.add(serializePropertyAccess(expr)); |
| 246 operations.add(UnlinkedConstOperation.pushReference); |
| 247 } |
| 248 } else if (expr is ParenthesizedExpression) { |
| 249 _serialize(expr.expression); |
| 250 } else { |
| 251 throw new StateError('Unknown expression type: $expr'); |
| 252 } |
| 253 } |
| 254 |
| 215 void _serializeBinaryExpression(BinaryExpression expr) { | 255 void _serializeBinaryExpression(BinaryExpression expr) { |
| 216 serialize(expr.leftOperand); | 256 _serialize(expr.leftOperand); |
| 217 serialize(expr.rightOperand); | 257 _serialize(expr.rightOperand); |
| 218 TokenType operator = expr.operator.type; | 258 TokenType operator = expr.operator.type; |
| 219 if (operator == TokenType.EQ_EQ) { | 259 if (operator == TokenType.EQ_EQ) { |
| 220 operations.add(UnlinkedConstOperation.equal); | 260 operations.add(UnlinkedConstOperation.equal); |
| 221 } else if (operator == TokenType.BANG_EQ) { | 261 } else if (operator == TokenType.BANG_EQ) { |
| 222 operations.add(UnlinkedConstOperation.notEqual); | 262 operations.add(UnlinkedConstOperation.notEqual); |
| 223 } else if (operator == TokenType.AMPERSAND_AMPERSAND) { | 263 } else if (operator == TokenType.AMPERSAND_AMPERSAND) { |
| 224 operations.add(UnlinkedConstOperation.and); | 264 operations.add(UnlinkedConstOperation.and); |
| 225 } else if (operator == TokenType.BAR_BAR) { | 265 } else if (operator == TokenType.BAR_BAR) { |
| 226 operations.add(UnlinkedConstOperation.or); | 266 operations.add(UnlinkedConstOperation.or); |
| 227 } else if (operator == TokenType.CARET) { | 267 } else if (operator == TokenType.CARET) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 248 operations.add(UnlinkedConstOperation.greater); | 288 operations.add(UnlinkedConstOperation.greater); |
| 249 } else if (operator == TokenType.LT) { | 289 } else if (operator == TokenType.LT) { |
| 250 operations.add(UnlinkedConstOperation.less); | 290 operations.add(UnlinkedConstOperation.less); |
| 251 } else if (operator == TokenType.GT_EQ) { | 291 } else if (operator == TokenType.GT_EQ) { |
| 252 operations.add(UnlinkedConstOperation.greaterEqual); | 292 operations.add(UnlinkedConstOperation.greaterEqual); |
| 253 } else if (operator == TokenType.LT_EQ) { | 293 } else if (operator == TokenType.LT_EQ) { |
| 254 operations.add(UnlinkedConstOperation.lessEqual); | 294 operations.add(UnlinkedConstOperation.lessEqual); |
| 255 } else if (operator == TokenType.PERCENT) { | 295 } else if (operator == TokenType.PERCENT) { |
| 256 operations.add(UnlinkedConstOperation.modulo); | 296 operations.add(UnlinkedConstOperation.modulo); |
| 257 } else { | 297 } else { |
| 258 throw new _ConstExprSerializationError('Unknown operator: $operator'); | 298 throw new StateError('Unknown operator: $operator'); |
| 259 } | 299 } |
| 260 } | 300 } |
| 261 | 301 |
| 262 void serializeInstanceCreation( | |
| 263 EntityRefBuilder constructor, ArgumentList argumentList) { | |
| 264 List<Expression> arguments = argumentList.arguments; | |
| 265 // Serialize the arguments. | |
| 266 List<String> argumentNames = <String>[]; | |
| 267 arguments.forEach((arg) { | |
| 268 if (arg is NamedExpression) { | |
| 269 argumentNames.add(arg.name.label.name); | |
| 270 serialize(arg.expression); | |
| 271 } else { | |
| 272 serialize(arg); | |
| 273 } | |
| 274 }); | |
| 275 // Add the op-code and numbers of named and positional arguments. | |
| 276 operations.add(UnlinkedConstOperation.invokeConstructor); | |
| 277 ints.add(argumentNames.length); | |
| 278 strings.addAll(argumentNames); | |
| 279 ints.add(arguments.length - argumentNames.length); | |
| 280 // Serialize the reference. | |
| 281 references.add(constructor); | |
| 282 } | |
| 283 | |
| 284 void _serializeListLiteral(ListLiteral expr) { | 302 void _serializeListLiteral(ListLiteral expr) { |
| 285 List<Expression> elements = expr.elements; | 303 List<Expression> elements = expr.elements; |
| 286 elements.forEach(serialize); | 304 elements.forEach(_serialize); |
| 287 ints.add(elements.length); | 305 ints.add(elements.length); |
| 288 if (expr.typeArguments != null && | 306 if (expr.typeArguments != null && |
| 289 expr.typeArguments.arguments.length == 1) { | 307 expr.typeArguments.arguments.length == 1) { |
| 290 references.add(serializeType(expr.typeArguments.arguments[0])); | 308 references.add(serializeType(expr.typeArguments.arguments[0])); |
| 291 operations.add(UnlinkedConstOperation.makeTypedList); | 309 operations.add(UnlinkedConstOperation.makeTypedList); |
| 292 } else { | 310 } else { |
| 293 operations.add(UnlinkedConstOperation.makeUntypedList); | 311 operations.add(UnlinkedConstOperation.makeUntypedList); |
| 294 } | 312 } |
| 295 } | 313 } |
| 296 | 314 |
| 297 void _serializeMapLiteral(MapLiteral expr) { | 315 void _serializeMapLiteral(MapLiteral expr) { |
| 298 for (MapLiteralEntry entry in expr.entries) { | 316 for (MapLiteralEntry entry in expr.entries) { |
| 299 serialize(entry.key); | 317 _serialize(entry.key); |
| 300 serialize(entry.value); | 318 _serialize(entry.value); |
| 301 } | 319 } |
| 302 ints.add(expr.entries.length); | 320 ints.add(expr.entries.length); |
| 303 if (expr.typeArguments != null && | 321 if (expr.typeArguments != null && |
| 304 expr.typeArguments.arguments.length == 2) { | 322 expr.typeArguments.arguments.length == 2) { |
| 305 references.add(serializeType(expr.typeArguments.arguments[0])); | 323 references.add(serializeType(expr.typeArguments.arguments[0])); |
| 306 references.add(serializeType(expr.typeArguments.arguments[1])); | 324 references.add(serializeType(expr.typeArguments.arguments[1])); |
| 307 operations.add(UnlinkedConstOperation.makeTypedMap); | 325 operations.add(UnlinkedConstOperation.makeTypedMap); |
| 308 } else { | 326 } else { |
| 309 operations.add(UnlinkedConstOperation.makeUntypedMap); | 327 operations.add(UnlinkedConstOperation.makeUntypedMap); |
| 310 } | 328 } |
| 311 } | 329 } |
| 312 | 330 |
| 313 void _serializePrefixExpression(PrefixExpression expr) { | 331 void _serializePrefixExpression(PrefixExpression expr) { |
| 314 serialize(expr.operand); | 332 _serialize(expr.operand); |
| 315 TokenType operator = expr.operator.type; | 333 TokenType operator = expr.operator.type; |
| 316 if (operator == TokenType.BANG) { | 334 if (operator == TokenType.BANG) { |
| 317 operations.add(UnlinkedConstOperation.not); | 335 operations.add(UnlinkedConstOperation.not); |
| 318 } else if (operator == TokenType.MINUS) { | 336 } else if (operator == TokenType.MINUS) { |
| 319 operations.add(UnlinkedConstOperation.negate); | 337 operations.add(UnlinkedConstOperation.negate); |
| 320 } else if (operator == TokenType.TILDE) { | 338 } else if (operator == TokenType.TILDE) { |
| 321 operations.add(UnlinkedConstOperation.complement); | 339 operations.add(UnlinkedConstOperation.complement); |
| 322 } else { | 340 } else { |
| 323 throw new _ConstExprSerializationError('Unknown operator: $operator'); | 341 throw new StateError('Unknown operator: $operator'); |
| 324 } | 342 } |
| 325 } | 343 } |
| 326 | 344 |
| 327 void _serializeString(StringLiteral expr) { | 345 void _serializeString(StringLiteral expr) { |
| 328 if (expr is AdjacentStrings) { | 346 if (expr is AdjacentStrings) { |
| 329 if (expr.strings.every((string) => string is SimpleStringLiteral)) { | 347 if (expr.strings.every((string) => string is SimpleStringLiteral)) { |
| 330 operations.add(UnlinkedConstOperation.pushString); | 348 operations.add(UnlinkedConstOperation.pushString); |
| 331 strings.add(expr.stringValue); | 349 strings.add(expr.stringValue); |
| 332 } else { | 350 } else { |
| 333 expr.strings.forEach(_serializeString); | 351 expr.strings.forEach(_serializeString); |
| 334 operations.add(UnlinkedConstOperation.concatenate); | 352 operations.add(UnlinkedConstOperation.concatenate); |
| 335 ints.add(expr.strings.length); | 353 ints.add(expr.strings.length); |
| 336 } | 354 } |
| 337 } else if (expr is SimpleStringLiteral) { | 355 } else if (expr is SimpleStringLiteral) { |
| 338 operations.add(UnlinkedConstOperation.pushString); | 356 operations.add(UnlinkedConstOperation.pushString); |
| 339 strings.add(expr.value); | 357 strings.add(expr.value); |
| 340 } else { | 358 } else { |
| 341 StringInterpolation interpolation = expr as StringInterpolation; | 359 StringInterpolation interpolation = expr as StringInterpolation; |
| 342 for (InterpolationElement element in interpolation.elements) { | 360 for (InterpolationElement element in interpolation.elements) { |
| 343 if (element is InterpolationString) { | 361 if (element is InterpolationString) { |
| 344 operations.add(UnlinkedConstOperation.pushString); | 362 operations.add(UnlinkedConstOperation.pushString); |
| 345 strings.add(element.value); | 363 strings.add(element.value); |
| 346 } else { | 364 } else { |
| 347 serialize((element as InterpolationExpression).expression); | 365 _serialize((element as InterpolationExpression).expression); |
| 348 } | 366 } |
| 349 } | 367 } |
| 350 operations.add(UnlinkedConstOperation.concatenate); | 368 operations.add(UnlinkedConstOperation.concatenate); |
| 351 ints.add(interpolation.elements.length); | 369 ints.add(interpolation.elements.length); |
| 352 } | 370 } |
| 353 } | 371 } |
| 354 } | 372 } |
| 355 | |
| 356 /** | |
| 357 * Error that describes a problem during a constant expression serialization. | |
| 358 */ | |
| 359 class _ConstExprSerializationError { | |
| 360 final String message; | |
| 361 | |
| 362 _ConstExprSerializationError(this.message); | |
| 363 | |
| 364 @override | |
| 365 String toString() => message; | |
| 366 } | |
| OLD | NEW |