| Index: pkg/analyzer/lib/src/summary/summarize_const_expr.dart
|
| diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
|
| index 70f1974459146d20333aab29aa62e2e98278779c..b644788706ac67cb619946543224b2051ef16b59 100644
|
| --- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
|
| +++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
|
| @@ -44,6 +44,11 @@ UnlinkedConstructorInitializer serializeConstructorInitializer(
|
| */
|
| abstract class AbstractConstExprSerializer {
|
| /**
|
| + * See [UnlinkedConstBuilder.isInvalid].
|
| + */
|
| + bool isInvalid = false;
|
| +
|
| + /**
|
| * See [UnlinkedConstBuilder.operations].
|
| */
|
| final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[];
|
| @@ -78,76 +83,10 @@ abstract class AbstractConstExprSerializer {
|
| * Serialize the given [expr] expression into this serializer state.
|
| */
|
| void serialize(Expression expr) {
|
| - if (expr is IntegerLiteral) {
|
| - _pushInt(expr.value);
|
| - } else if (expr is DoubleLiteral) {
|
| - operations.add(UnlinkedConstOperation.pushDouble);
|
| - doubles.add(expr.value);
|
| - } else if (expr is BooleanLiteral) {
|
| - if (expr.value) {
|
| - operations.add(UnlinkedConstOperation.pushTrue);
|
| - } else {
|
| - operations.add(UnlinkedConstOperation.pushFalse);
|
| - }
|
| - } else if (expr is StringLiteral) {
|
| - _serializeString(expr);
|
| - } else if (expr is SymbolLiteral) {
|
| - strings.add(expr.components.map((token) => token.lexeme).join('.'));
|
| - operations.add(UnlinkedConstOperation.makeSymbol);
|
| - } else if (expr is NullLiteral) {
|
| - operations.add(UnlinkedConstOperation.pushNull);
|
| - } else if (expr is Identifier) {
|
| - if (expr is SimpleIdentifier && isConstructorParameterName(expr.name)) {
|
| - strings.add(expr.name);
|
| - operations.add(UnlinkedConstOperation.pushConstructorParameter);
|
| - } else {
|
| - references.add(serializeIdentifier(expr));
|
| - operations.add(UnlinkedConstOperation.pushReference);
|
| - }
|
| - } else if (expr is InstanceCreationExpression) {
|
| - serializeInstanceCreation(
|
| - serializeConstructorName(
|
| - expr.constructorName.type, expr.constructorName.name),
|
| - expr.argumentList);
|
| - } else if (expr is ListLiteral) {
|
| - _serializeListLiteral(expr);
|
| - } else if (expr is MapLiteral) {
|
| - _serializeMapLiteral(expr);
|
| - } else if (expr is MethodInvocation) {
|
| - String name = expr.methodName.name;
|
| - if (name != 'identical') {
|
| - throw new _ConstExprSerializationError(
|
| - 'Only "identity" function invocation is allowed.');
|
| - }
|
| - if (expr.argumentList == null ||
|
| - expr.argumentList.arguments.length != 2) {
|
| - throw new _ConstExprSerializationError(
|
| - 'The function "identity" requires exactly 2 arguments.');
|
| - }
|
| - expr.argumentList.arguments.forEach(serialize);
|
| - operations.add(UnlinkedConstOperation.identical);
|
| - } else if (expr is BinaryExpression) {
|
| - _serializeBinaryExpression(expr);
|
| - } else if (expr is ConditionalExpression) {
|
| - serialize(expr.condition);
|
| - serialize(expr.thenExpression);
|
| - serialize(expr.elseExpression);
|
| - operations.add(UnlinkedConstOperation.conditional);
|
| - } else if (expr is PrefixExpression) {
|
| - _serializePrefixExpression(expr);
|
| - } else if (expr is PropertyAccess) {
|
| - if (expr.target is! PrefixedIdentifier &&
|
| - expr.propertyName.name == 'length') {
|
| - serialize(expr.target);
|
| - operations.add(UnlinkedConstOperation.length);
|
| - } else {
|
| - references.add(serializePropertyAccess(expr));
|
| - operations.add(UnlinkedConstOperation.pushReference);
|
| - }
|
| - } else if (expr is ParenthesizedExpression) {
|
| - serialize(expr.expression);
|
| - } else {
|
| - throw new _ConstExprSerializationError('Unknown expression type: $expr');
|
| + try {
|
| + _serialize(expr);
|
| + } on StateError {
|
| + isInvalid = true;
|
| }
|
| }
|
|
|
| @@ -168,6 +107,28 @@ abstract class AbstractConstExprSerializer {
|
| */
|
| EntityRefBuilder serializeIdentifier(Identifier identifier);
|
|
|
| + void serializeInstanceCreation(
|
| + EntityRefBuilder constructor, ArgumentList argumentList) {
|
| + List<Expression> arguments = argumentList.arguments;
|
| + // Serialize the arguments.
|
| + List<String> argumentNames = <String>[];
|
| + arguments.forEach((arg) {
|
| + if (arg is NamedExpression) {
|
| + argumentNames.add(arg.name.label.name);
|
| + _serialize(arg.expression);
|
| + } else {
|
| + _serialize(arg);
|
| + }
|
| + });
|
| + // Add the op-code and numbers of named and positional arguments.
|
| + operations.add(UnlinkedConstOperation.invokeConstructor);
|
| + ints.add(argumentNames.length);
|
| + strings.addAll(argumentNames);
|
| + ints.add(arguments.length - argumentNames.length);
|
| + // Serialize the reference.
|
| + references.add(constructor);
|
| + }
|
| +
|
| /**
|
| * Return [EntityRefBuilder] that corresponds to the given [access].
|
| */
|
| @@ -183,6 +144,9 @@ abstract class AbstractConstExprSerializer {
|
| * serializer.
|
| */
|
| UnlinkedConstBuilder toBuilder() {
|
| + if (isInvalid) {
|
| + return new UnlinkedConstBuilder(isInvalid: true);
|
| + }
|
| return new UnlinkedConstBuilder(
|
| operations: operations,
|
| ints: ints,
|
| @@ -212,9 +176,85 @@ abstract class AbstractConstExprSerializer {
|
| }
|
| }
|
|
|
| + /**
|
| + * Serialize the given [expr] expression into this serializer state.
|
| + */
|
| + void _serialize(Expression expr) {
|
| + if (expr is IntegerLiteral) {
|
| + _pushInt(expr.value);
|
| + } else if (expr is DoubleLiteral) {
|
| + operations.add(UnlinkedConstOperation.pushDouble);
|
| + doubles.add(expr.value);
|
| + } else if (expr is BooleanLiteral) {
|
| + if (expr.value) {
|
| + operations.add(UnlinkedConstOperation.pushTrue);
|
| + } else {
|
| + operations.add(UnlinkedConstOperation.pushFalse);
|
| + }
|
| + } else if (expr is StringLiteral) {
|
| + _serializeString(expr);
|
| + } else if (expr is SymbolLiteral) {
|
| + strings.add(expr.components.map((token) => token.lexeme).join('.'));
|
| + operations.add(UnlinkedConstOperation.makeSymbol);
|
| + } else if (expr is NullLiteral) {
|
| + operations.add(UnlinkedConstOperation.pushNull);
|
| + } else if (expr is Identifier) {
|
| + if (expr is SimpleIdentifier && isConstructorParameterName(expr.name)) {
|
| + strings.add(expr.name);
|
| + operations.add(UnlinkedConstOperation.pushConstructorParameter);
|
| + } else {
|
| + references.add(serializeIdentifier(expr));
|
| + operations.add(UnlinkedConstOperation.pushReference);
|
| + }
|
| + } else if (expr is InstanceCreationExpression) {
|
| + serializeInstanceCreation(
|
| + serializeConstructorName(
|
| + expr.constructorName.type, expr.constructorName.name),
|
| + expr.argumentList);
|
| + } else if (expr is ListLiteral) {
|
| + _serializeListLiteral(expr);
|
| + } else if (expr is MapLiteral) {
|
| + _serializeMapLiteral(expr);
|
| + } else if (expr is MethodInvocation) {
|
| + String name = expr.methodName.name;
|
| + if (name != 'identical') {
|
| + throw new StateError('Only "identity" function invocation is allowed.');
|
| + }
|
| + if (expr.argumentList == null ||
|
| + expr.argumentList.arguments.length != 2) {
|
| + throw new StateError(
|
| + 'The function "identity" requires exactly 2 arguments.');
|
| + }
|
| + expr.argumentList.arguments.forEach(_serialize);
|
| + operations.add(UnlinkedConstOperation.identical);
|
| + } else if (expr is BinaryExpression) {
|
| + _serializeBinaryExpression(expr);
|
| + } else if (expr is ConditionalExpression) {
|
| + _serialize(expr.condition);
|
| + _serialize(expr.thenExpression);
|
| + _serialize(expr.elseExpression);
|
| + operations.add(UnlinkedConstOperation.conditional);
|
| + } else if (expr is PrefixExpression) {
|
| + _serializePrefixExpression(expr);
|
| + } else if (expr is PropertyAccess) {
|
| + if (expr.target is! PrefixedIdentifier &&
|
| + expr.propertyName.name == 'length') {
|
| + _serialize(expr.target);
|
| + operations.add(UnlinkedConstOperation.length);
|
| + } else {
|
| + references.add(serializePropertyAccess(expr));
|
| + operations.add(UnlinkedConstOperation.pushReference);
|
| + }
|
| + } else if (expr is ParenthesizedExpression) {
|
| + _serialize(expr.expression);
|
| + } else {
|
| + throw new StateError('Unknown expression type: $expr');
|
| + }
|
| + }
|
| +
|
| void _serializeBinaryExpression(BinaryExpression expr) {
|
| - serialize(expr.leftOperand);
|
| - serialize(expr.rightOperand);
|
| + _serialize(expr.leftOperand);
|
| + _serialize(expr.rightOperand);
|
| TokenType operator = expr.operator.type;
|
| if (operator == TokenType.EQ_EQ) {
|
| operations.add(UnlinkedConstOperation.equal);
|
| @@ -255,35 +295,13 @@ abstract class AbstractConstExprSerializer {
|
| } else if (operator == TokenType.PERCENT) {
|
| operations.add(UnlinkedConstOperation.modulo);
|
| } else {
|
| - throw new _ConstExprSerializationError('Unknown operator: $operator');
|
| + throw new StateError('Unknown operator: $operator');
|
| }
|
| }
|
|
|
| - void serializeInstanceCreation(
|
| - EntityRefBuilder constructor, ArgumentList argumentList) {
|
| - List<Expression> arguments = argumentList.arguments;
|
| - // Serialize the arguments.
|
| - List<String> argumentNames = <String>[];
|
| - arguments.forEach((arg) {
|
| - if (arg is NamedExpression) {
|
| - argumentNames.add(arg.name.label.name);
|
| - serialize(arg.expression);
|
| - } else {
|
| - serialize(arg);
|
| - }
|
| - });
|
| - // Add the op-code and numbers of named and positional arguments.
|
| - operations.add(UnlinkedConstOperation.invokeConstructor);
|
| - ints.add(argumentNames.length);
|
| - strings.addAll(argumentNames);
|
| - ints.add(arguments.length - argumentNames.length);
|
| - // Serialize the reference.
|
| - references.add(constructor);
|
| - }
|
| -
|
| void _serializeListLiteral(ListLiteral expr) {
|
| List<Expression> elements = expr.elements;
|
| - elements.forEach(serialize);
|
| + elements.forEach(_serialize);
|
| ints.add(elements.length);
|
| if (expr.typeArguments != null &&
|
| expr.typeArguments.arguments.length == 1) {
|
| @@ -296,8 +314,8 @@ abstract class AbstractConstExprSerializer {
|
|
|
| void _serializeMapLiteral(MapLiteral expr) {
|
| for (MapLiteralEntry entry in expr.entries) {
|
| - serialize(entry.key);
|
| - serialize(entry.value);
|
| + _serialize(entry.key);
|
| + _serialize(entry.value);
|
| }
|
| ints.add(expr.entries.length);
|
| if (expr.typeArguments != null &&
|
| @@ -311,7 +329,7 @@ abstract class AbstractConstExprSerializer {
|
| }
|
|
|
| void _serializePrefixExpression(PrefixExpression expr) {
|
| - serialize(expr.operand);
|
| + _serialize(expr.operand);
|
| TokenType operator = expr.operator.type;
|
| if (operator == TokenType.BANG) {
|
| operations.add(UnlinkedConstOperation.not);
|
| @@ -320,7 +338,7 @@ abstract class AbstractConstExprSerializer {
|
| } else if (operator == TokenType.TILDE) {
|
| operations.add(UnlinkedConstOperation.complement);
|
| } else {
|
| - throw new _ConstExprSerializationError('Unknown operator: $operator');
|
| + throw new StateError('Unknown operator: $operator');
|
| }
|
| }
|
|
|
| @@ -344,7 +362,7 @@ abstract class AbstractConstExprSerializer {
|
| operations.add(UnlinkedConstOperation.pushString);
|
| strings.add(element.value);
|
| } else {
|
| - serialize((element as InterpolationExpression).expression);
|
| + _serialize((element as InterpolationExpression).expression);
|
| }
|
| }
|
| operations.add(UnlinkedConstOperation.concatenate);
|
| @@ -352,15 +370,3 @@ abstract class AbstractConstExprSerializer {
|
| }
|
| }
|
| }
|
| -
|
| -/**
|
| - * Error that describes a problem during a constant expression serialization.
|
| - */
|
| -class _ConstExprSerializationError {
|
| - final String message;
|
| -
|
| - _ConstExprSerializationError(this.message);
|
| -
|
| - @override
|
| - String toString() => message;
|
| -}
|
|
|