Add support for "??" to summaries.

R=scheglov@google.com

Review URL: https://codereview.chromium.org/2514353005 .
This commit is contained in:
Paul Berry 2016-11-22 10:10:19 -08:00
parent 5ee71cae9d
commit 3a6972095f
7 changed files with 49 additions and 1 deletions

View file

@ -758,7 +758,14 @@ enum UnlinkedExprOperation : byte {
* the nth enclosing function element. Then, push the mth local function of
* that element onto the stack.
*/
pushLocalFunctionReference
pushLocalFunctionReference,
/**
* Pop the top two values from the stack. If the first value is non-null,
* keep it and discard the second. Otherwise, keep the second and discard the
* first.
*/
ifNull
}
/**

View file

@ -2333,6 +2333,13 @@ enum UnlinkedExprOperation {
* that element onto the stack.
*/
pushLocalFunctionReference,
/**
* Pop the top two values from the stack. If the first value is non-null,
* keep it and discard the second. Otherwise, keep the second and discard the
* first.
*/
ifNull,
}
/**

View file

@ -2265,6 +2265,9 @@ class ExprTypeComputer {
case UnlinkedExprOperation.pushParameter:
stack.add(_findParameterType(_getNextString()));
break;
case UnlinkedExprOperation.ifNull:
_doIfNull();
break;
default:
// TODO(paulberry): implement.
throw new UnimplementedError('$operation');
@ -2404,6 +2407,14 @@ class ExprTypeComputer {
}());
}
void _doIfNull() {
DartType secondType = stack.removeLast();
DartType firstType = stack.removeLast();
DartType type = _leastUpperBound(firstType, secondType);
type = _dynamicIfNull(type);
stack.add(type);
}
void _doInvokeConstructor() {
int numNamed = _getNextInt();
int numPositional = _getNextInt();

View file

@ -496,6 +496,9 @@ class _ConstExprBuilder {
'Unable to resolve constructor parameter: $name'));
_push(identifier);
break;
case UnlinkedExprOperation.ifNull:
_pushBinary(TokenType.QUESTION_QUESTION);
break;
case UnlinkedExprOperation.assignToRef:
case UnlinkedExprOperation.assignToProperty:
case UnlinkedExprOperation.assignToIndex:

View file

@ -486,6 +486,8 @@ abstract class AbstractConstExprSerializer {
operations.add(UnlinkedExprOperation.lessEqual);
} else if (operator == TokenType.PERCENT) {
operations.add(UnlinkedExprOperation.modulo);
} else if (operator == TokenType.QUESTION_QUESTION) {
operations.add(UnlinkedExprOperation.ifNull);
} else {
throw new StateError('Unknown operator: $operator');
}

View file

@ -2302,6 +2302,12 @@ const vIdentical = (1 == 2) ? 11 : 22;
''');
}
test_const_topLevel_ifNull() {
checkLibrary(r'''
const vIfNull = 1 ?? 2.0;
''');
}
test_const_topLevel_literal() {
checkLibrary(r'''
const vNull = null;

View file

@ -1755,6 +1755,18 @@ var v = (() {
]);
}
test_constExpr_binary_qq() {
UnlinkedVariable variable = serializeVariableText('const v = 1 ?? 2;');
_assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
UnlinkedExprOperation.pushInt,
UnlinkedExprOperation.pushInt,
UnlinkedExprOperation.ifNull
], ints: [
1,
2
]);
}
test_constExpr_binary_subtract() {
UnlinkedVariable variable = serializeVariableText('const v = 1 - 2;');
_assertUnlinkedConst(variable.initializer.bodyExpr, operators: [