| 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/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/ast/token.dart'; | 8 import 'package:analyzer/dart/ast/token.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 28 matching lines...) Expand all Loading... |
| 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]. | 47 * See [UnlinkedConstBuilder.isInvalid]. |
| 48 */ | 48 */ |
| 49 bool isInvalid = false; | 49 bool isValidConst = true; |
| 50 | 50 |
| 51 /** | 51 /** |
| 52 * See [UnlinkedConstBuilder.operations]. | 52 * See [UnlinkedConstBuilder.operations]. |
| 53 */ | 53 */ |
| 54 final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[]; | 54 final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[]; |
| 55 | 55 |
| 56 /** | 56 /** |
| 57 * See [UnlinkedConstBuilder.assignmentOperators]. | 57 * See [UnlinkedConstBuilder.assignmentOperators]. |
| 58 */ | 58 */ |
| 59 final List<UnlinkedExprAssignOperator> assignmentOperators = | 59 final List<UnlinkedExprAssignOperator> assignmentOperators = |
| (...skipping 25 matching lines...) Expand all Loading... |
| 85 */ | 85 */ |
| 86 bool isConstructorParameterName(String name); | 86 bool isConstructorParameterName(String name); |
| 87 | 87 |
| 88 /** | 88 /** |
| 89 * Serialize the given [expr] expression into this serializer state. | 89 * Serialize the given [expr] expression into this serializer state. |
| 90 */ | 90 */ |
| 91 void serialize(Expression expr) { | 91 void serialize(Expression expr) { |
| 92 try { | 92 try { |
| 93 _serialize(expr); | 93 _serialize(expr); |
| 94 } on StateError { | 94 } on StateError { |
| 95 isInvalid = true; | 95 isValidConst = false; |
| 96 } | 96 } |
| 97 } | 97 } |
| 98 | 98 |
| 99 /** | 99 /** |
| 100 * Serialize the given [annotation] into this serializer state. | 100 * Serialize the given [annotation] into this serializer state. |
| 101 */ | 101 */ |
| 102 void serializeAnnotation(Annotation annotation); | 102 void serializeAnnotation(Annotation annotation); |
| 103 | 103 |
| 104 /** | 104 /** |
| 105 * Return [EntityRefBuilder] that corresponds to the constructor having name | 105 * Return [EntityRefBuilder] that corresponds to the constructor having name |
| (...skipping 23 matching lines...) Expand all Loading... |
| 129 /** | 129 /** |
| 130 * Return [EntityRefBuilder] that corresponds to the given [type]. | 130 * Return [EntityRefBuilder] that corresponds to the given [type]. |
| 131 */ | 131 */ |
| 132 EntityRefBuilder serializeType(TypeName type); | 132 EntityRefBuilder serializeType(TypeName type); |
| 133 | 133 |
| 134 /** | 134 /** |
| 135 * Return the [UnlinkedConstBuilder] that corresponds to the state of this | 135 * Return the [UnlinkedConstBuilder] that corresponds to the state of this |
| 136 * serializer. | 136 * serializer. |
| 137 */ | 137 */ |
| 138 UnlinkedConstBuilder toBuilder() { | 138 UnlinkedConstBuilder toBuilder() { |
| 139 if (isInvalid) { | |
| 140 return new UnlinkedConstBuilder(isInvalid: true); | |
| 141 } | |
| 142 return new UnlinkedConstBuilder( | 139 return new UnlinkedConstBuilder( |
| 140 isValidConst: isValidConst, |
| 143 operations: operations, | 141 operations: operations, |
| 144 assignmentOperators: assignmentOperators, | 142 assignmentOperators: assignmentOperators, |
| 145 ints: ints, | 143 ints: ints, |
| 146 doubles: doubles, | 144 doubles: doubles, |
| 147 strings: strings, | 145 strings: strings, |
| 148 references: references); | 146 references: references); |
| 149 } | 147 } |
| 150 | 148 |
| 151 /** | 149 /** |
| 152 * Push the operation for the given assignable [expr]. | 150 * Push the operation for the given assignable [expr]. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 operations.add(UnlinkedConstOperation.pushNull); | 216 operations.add(UnlinkedConstOperation.pushNull); |
| 219 } else if (expr is Identifier) { | 217 } else if (expr is Identifier) { |
| 220 if (expr is SimpleIdentifier && isConstructorParameterName(expr.name)) { | 218 if (expr is SimpleIdentifier && isConstructorParameterName(expr.name)) { |
| 221 strings.add(expr.name); | 219 strings.add(expr.name); |
| 222 operations.add(UnlinkedConstOperation.pushConstructorParameter); | 220 operations.add(UnlinkedConstOperation.pushConstructorParameter); |
| 223 } else { | 221 } else { |
| 224 references.add(serializeIdentifier(expr)); | 222 references.add(serializeIdentifier(expr)); |
| 225 operations.add(UnlinkedConstOperation.pushReference); | 223 operations.add(UnlinkedConstOperation.pushReference); |
| 226 } | 224 } |
| 227 } else if (expr is InstanceCreationExpression) { | 225 } else if (expr is InstanceCreationExpression) { |
| 226 if (!expr.isConst) { |
| 227 isValidConst = false; |
| 228 } |
| 228 serializeInstanceCreation( | 229 serializeInstanceCreation( |
| 229 serializeConstructorName( | 230 serializeConstructorName( |
| 230 expr.constructorName.type, expr.constructorName.name), | 231 expr.constructorName.type, expr.constructorName.name), |
| 231 expr.argumentList); | 232 expr.argumentList); |
| 232 } else if (expr is ListLiteral) { | 233 } else if (expr is ListLiteral) { |
| 233 _serializeListLiteral(expr); | 234 _serializeListLiteral(expr); |
| 234 } else if (expr is MapLiteral) { | 235 } else if (expr is MapLiteral) { |
| 235 _serializeMapLiteral(expr); | 236 _serializeMapLiteral(expr); |
| 236 } else if (expr is MethodInvocation) { | 237 } else if (expr is MethodInvocation) { |
| 237 _serializeMethodInvocation(expr); | 238 _serializeMethodInvocation(expr); |
| 238 } else if (expr is BinaryExpression) { | 239 } else if (expr is BinaryExpression) { |
| 239 _serializeBinaryExpression(expr); | 240 _serializeBinaryExpression(expr); |
| 240 } else if (expr is ConditionalExpression) { | 241 } else if (expr is ConditionalExpression) { |
| 241 _serialize(expr.condition); | 242 _serialize(expr.condition); |
| 242 _serialize(expr.thenExpression); | 243 _serialize(expr.thenExpression); |
| 243 _serialize(expr.elseExpression); | 244 _serialize(expr.elseExpression); |
| 244 operations.add(UnlinkedConstOperation.conditional); | 245 operations.add(UnlinkedConstOperation.conditional); |
| 245 } else if (expr is PrefixExpression) { | 246 } else if (expr is PrefixExpression) { |
| 246 _serializePrefixExpression(expr); | 247 _serializePrefixExpression(expr); |
| 247 } else if (expr is PostfixExpression) { | 248 } else if (expr is PostfixExpression) { |
| 248 _serializePostfixExpression(expr); | 249 _serializePostfixExpression(expr); |
| 249 } else if (expr is PropertyAccess) { | 250 } else if (expr is PropertyAccess) { |
| 250 _serializePropertyAccess(expr); | 251 _serializePropertyAccess(expr); |
| 251 } else if (expr is ParenthesizedExpression) { | 252 } else if (expr is ParenthesizedExpression) { |
| 252 _serialize(expr.expression); | 253 _serialize(expr.expression); |
| 253 } else if (expr is IndexExpression) { | 254 } else if (expr is IndexExpression) { |
| 255 isValidConst = false; |
| 254 _serialize(expr.target); | 256 _serialize(expr.target); |
| 255 _serialize(expr.index); | 257 _serialize(expr.index); |
| 256 operations.add(UnlinkedConstOperation.extractIndex); | 258 operations.add(UnlinkedConstOperation.extractIndex); |
| 257 } else if (expr is AssignmentExpression) { | 259 } else if (expr is AssignmentExpression) { |
| 258 _serializeAssignment(expr); | 260 _serializeAssignment(expr); |
| 259 } else if (expr is CascadeExpression) { | 261 } else if (expr is CascadeExpression) { |
| 260 _serializeCascadeExpression(expr); | 262 _serializeCascadeExpression(expr); |
| 261 } else if (expr is FunctionExpression) { | 263 } else if (expr is FunctionExpression) { |
| 264 isValidConst = false; |
| 262 // TODO(scheglov) implement | 265 // TODO(scheglov) implement |
| 263 operations.add(UnlinkedConstOperation.pushNull); | 266 operations.add(UnlinkedConstOperation.pushNull); |
| 264 } else if (expr is FunctionExpressionInvocation) { | 267 } else if (expr is FunctionExpressionInvocation) { |
| 268 isValidConst = false; |
| 265 // TODO(scheglov) implement | 269 // TODO(scheglov) implement |
| 266 operations.add(UnlinkedConstOperation.pushNull); | 270 operations.add(UnlinkedConstOperation.pushNull); |
| 267 } else if (expr is AsExpression) { | 271 } else if (expr is AsExpression) { |
| 272 isValidConst = false; |
| 268 _serialize(expr.expression); | 273 _serialize(expr.expression); |
| 269 _serialize(expr.type.name); | 274 _serialize(expr.type.name); |
| 270 operations.add(UnlinkedConstOperation.typeCast); | 275 operations.add(UnlinkedConstOperation.typeCast); |
| 271 } else if (expr is IsExpression) { | 276 } else if (expr is IsExpression) { |
| 277 isValidConst = false; |
| 272 _serialize(expr.expression); | 278 _serialize(expr.expression); |
| 273 _serialize(expr.type.name); | 279 _serialize(expr.type.name); |
| 274 operations.add(UnlinkedConstOperation.typeCheck); | 280 operations.add(UnlinkedConstOperation.typeCheck); |
| 275 } else if (expr is ThrowExpression) { | 281 } else if (expr is ThrowExpression) { |
| 282 isValidConst = false; |
| 276 _serialize(expr.expression); | 283 _serialize(expr.expression); |
| 277 operations.add(UnlinkedConstOperation.throwException); | 284 operations.add(UnlinkedConstOperation.throwException); |
| 278 } else { | 285 } else { |
| 279 throw new StateError('Unknown expression type: $expr'); | 286 throw new StateError('Unknown expression type: $expr'); |
| 280 } | 287 } |
| 281 } | 288 } |
| 282 | 289 |
| 283 void _serializeArguments(ArgumentList argumentList) { | 290 void _serializeArguments(ArgumentList argumentList) { |
| 284 List<Expression> arguments = argumentList.arguments; | 291 List<Expression> arguments = argumentList.arguments; |
| 285 // Serialize the arguments. | 292 // Serialize the arguments. |
| 286 List<String> argumentNames = <String>[]; | 293 List<String> argumentNames = <String>[]; |
| 287 arguments.forEach((arg) { | 294 arguments.forEach((arg) { |
| 288 if (arg is NamedExpression) { | 295 if (arg is NamedExpression) { |
| 289 argumentNames.add(arg.name.label.name); | 296 argumentNames.add(arg.name.label.name); |
| 290 _serialize(arg.expression); | 297 _serialize(arg.expression); |
| 291 } else { | 298 } else { |
| 292 _serialize(arg); | 299 _serialize(arg); |
| 293 } | 300 } |
| 294 }); | 301 }); |
| 295 // Add numbers of named and positional arguments, and the op-code. | 302 // Add numbers of named and positional arguments, and the op-code. |
| 296 ints.add(argumentNames.length); | 303 ints.add(argumentNames.length); |
| 297 strings.addAll(argumentNames); | 304 strings.addAll(argumentNames); |
| 298 ints.add(arguments.length - argumentNames.length); | 305 ints.add(arguments.length - argumentNames.length); |
| 299 } | 306 } |
| 300 | 307 |
| 301 void _serializeAssignment(AssignmentExpression expr) { | 308 void _serializeAssignment(AssignmentExpression expr) { |
| 309 isValidConst = false; |
| 302 // Push the value. | 310 // Push the value. |
| 303 _serialize(expr.rightHandSide); | 311 _serialize(expr.rightHandSide); |
| 304 // Push the assignment operator. | 312 // Push the assignment operator. |
| 305 TokenType operator = expr.operator.type; | 313 TokenType operator = expr.operator.type; |
| 306 UnlinkedExprAssignOperator assignmentOperator; | 314 UnlinkedExprAssignOperator assignmentOperator; |
| 307 if (operator == TokenType.EQ) { | 315 if (operator == TokenType.EQ) { |
| 308 assignmentOperator = UnlinkedExprAssignOperator.assign; | 316 assignmentOperator = UnlinkedExprAssignOperator.assign; |
| 309 } else if (operator == TokenType.QUESTION_QUESTION_EQ) { | 317 } else if (operator == TokenType.QUESTION_QUESTION_EQ) { |
| 310 assignmentOperator = UnlinkedExprAssignOperator.ifNull; | 318 assignmentOperator = UnlinkedExprAssignOperator.ifNull; |
| 311 } else if (operator == TokenType.STAR_EQ) { | 319 } else if (operator == TokenType.STAR_EQ) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 expr.typeArguments.arguments.length == 2) { | 425 expr.typeArguments.arguments.length == 2) { |
| 418 references.add(serializeType(expr.typeArguments.arguments[0])); | 426 references.add(serializeType(expr.typeArguments.arguments[0])); |
| 419 references.add(serializeType(expr.typeArguments.arguments[1])); | 427 references.add(serializeType(expr.typeArguments.arguments[1])); |
| 420 operations.add(UnlinkedConstOperation.makeTypedMap); | 428 operations.add(UnlinkedConstOperation.makeTypedMap); |
| 421 } else { | 429 } else { |
| 422 operations.add(UnlinkedConstOperation.makeUntypedMap); | 430 operations.add(UnlinkedConstOperation.makeUntypedMap); |
| 423 } | 431 } |
| 424 } | 432 } |
| 425 | 433 |
| 426 void _serializeMethodInvocation(MethodInvocation invocation) { | 434 void _serializeMethodInvocation(MethodInvocation invocation) { |
| 435 if (invocation.target != null || |
| 436 invocation.methodName.name != 'identical') { |
| 437 isValidConst = false; |
| 438 } |
| 427 Expression target = invocation.target; | 439 Expression target = invocation.target; |
| 428 SimpleIdentifier methodName = invocation.methodName; | 440 SimpleIdentifier methodName = invocation.methodName; |
| 429 ArgumentList argumentList = invocation.argumentList; | 441 ArgumentList argumentList = invocation.argumentList; |
| 430 if (_isIdentifierSequence(methodName)) { | 442 if (_isIdentifierSequence(methodName)) { |
| 431 EntityRefBuilder ref = serializeIdentifierSequence(methodName); | 443 EntityRefBuilder ref = serializeIdentifierSequence(methodName); |
| 432 references.add(ref); | 444 references.add(ref); |
| 433 _serializeArguments(argumentList); | 445 _serializeArguments(argumentList); |
| 434 operations.add(UnlinkedConstOperation.invokeMethodRef); | 446 operations.add(UnlinkedConstOperation.invokeMethodRef); |
| 435 } else { | 447 } else { |
| 436 if (!invocation.isCascaded) { | 448 if (!invocation.isCascaded) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 } else if (operator == TokenType.MINUS_MINUS) { | 486 } else if (operator == TokenType.MINUS_MINUS) { |
| 475 _serializePrefixPostfixIncDec( | 487 _serializePrefixPostfixIncDec( |
| 476 operand, UnlinkedExprAssignOperator.prefixDecrement); | 488 operand, UnlinkedExprAssignOperator.prefixDecrement); |
| 477 } else { | 489 } else { |
| 478 throw new StateError('Unknown operator: $operator'); | 490 throw new StateError('Unknown operator: $operator'); |
| 479 } | 491 } |
| 480 } | 492 } |
| 481 | 493 |
| 482 void _serializePrefixPostfixIncDec( | 494 void _serializePrefixPostfixIncDec( |
| 483 Expression operand, UnlinkedExprAssignOperator operator) { | 495 Expression operand, UnlinkedExprAssignOperator operator) { |
| 496 isValidConst = false; |
| 484 assignmentOperators.add(operator); | 497 assignmentOperators.add(operator); |
| 485 _pushAssignable(operand); | 498 _pushAssignable(operand); |
| 486 } | 499 } |
| 487 | 500 |
| 488 void _serializePropertyAccess(PropertyAccess expr) { | 501 void _serializePropertyAccess(PropertyAccess expr) { |
| 489 if (_isIdentifierSequence(expr)) { | 502 if (_isIdentifierSequence(expr)) { |
| 490 EntityRefBuilder ref = serializeIdentifierSequence(expr); | 503 EntityRefBuilder ref = serializeIdentifierSequence(expr); |
| 491 references.add(ref); | 504 references.add(ref); |
| 492 operations.add(UnlinkedConstOperation.pushReference); | 505 operations.add(UnlinkedConstOperation.pushReference); |
| 493 } else { | 506 } else { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 expr = (expr as PrefixedIdentifier).prefix; | 556 expr = (expr as PrefixedIdentifier).prefix; |
| 544 } else if (expr is PropertyAccess) { | 557 } else if (expr is PropertyAccess) { |
| 545 expr = (expr as PropertyAccess).target; | 558 expr = (expr as PropertyAccess).target; |
| 546 } else { | 559 } else { |
| 547 return false; | 560 return false; |
| 548 } | 561 } |
| 549 } | 562 } |
| 550 return false; | 563 return false; |
| 551 } | 564 } |
| 552 } | 565 } |
| OLD | NEW |