mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:39:49 +00:00
Support for AwaitExpression in unlinked expressions.
This code was failing when analyzing dev_compiler with the new driver. var instanceVarArrowExpression = (f) async => await f; The reason was that we: 1. Don't understand AwaitExpression in AbstractConstExprSerializer. 2. So, we throw StateError. 3. So, AbstractConstExprSerializer.serialize() marks isValidConst. 4. But we don't check 'isValidConst' in linker. 5. The list of operations is empty, so we don't have anything in stack. 6. So, we throw an exception in linker. R=paulberry@google.com BUG= Review URL: https://codereview.chromium.org/2541603002 .
This commit is contained in:
parent
4cdb5534bf
commit
38635ec91e
|
@ -71,7 +71,7 @@ class AnalysisDriver {
|
|||
/**
|
||||
* The version of data format, should be incremented on every format change.
|
||||
*/
|
||||
static const int DATA_VERSION = 8;
|
||||
static const int DATA_VERSION = 9;
|
||||
|
||||
/**
|
||||
* The name of the driver, e.g. the name of the folder.
|
||||
|
|
|
@ -765,7 +765,13 @@ enum UnlinkedExprOperation : byte {
|
|||
* keep it and discard the second. Otherwise, keep the second and discard the
|
||||
* first.
|
||||
*/
|
||||
ifNull
|
||||
ifNull,
|
||||
|
||||
/**
|
||||
* Pop the top value from the stack. Treat it as a Future and await its
|
||||
* completion. Then push the awaited value onto the stack.
|
||||
*/
|
||||
await
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2341,6 +2341,12 @@ enum UnlinkedExprOperation {
|
|||
* first.
|
||||
*/
|
||||
ifNull,
|
||||
|
||||
/**
|
||||
* Pop the top value from the stack. Treat it as a Future and await its
|
||||
* completion. Then push the awaited value onto the stack.
|
||||
*/
|
||||
await,
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2228,6 +2228,9 @@ class ExprTypeComputer {
|
|||
case UnlinkedExprOperation.assignToIndex:
|
||||
_doAssignToIndex();
|
||||
break;
|
||||
case UnlinkedExprOperation.await:
|
||||
_doAwait();
|
||||
break;
|
||||
case UnlinkedExprOperation.extractIndex:
|
||||
_doExtractIndex();
|
||||
break;
|
||||
|
@ -2363,6 +2366,13 @@ class ExprTypeComputer {
|
|||
}
|
||||
}
|
||||
|
||||
void _doAwait() {
|
||||
DartType type = stack.removeLast();
|
||||
DartType typeArgument = type?.flattenFutures(linker.typeSystem);
|
||||
typeArgument = _dynamicIfNull(typeArgument);
|
||||
stack.add(typeArgument);
|
||||
}
|
||||
|
||||
void _doConditional() {
|
||||
DartType elseType = stack.removeLast();
|
||||
DartType thenType = stack.removeLast();
|
||||
|
@ -3413,10 +3423,10 @@ abstract class LibraryElementForLink<
|
|||
_linkedLibrary.importDependencies.map(_getDependency).toList();
|
||||
|
||||
@override
|
||||
bool get isDartAsync => _absoluteUri == 'dart:async';
|
||||
bool get isDartAsync => _absoluteUri.toString() == 'dart:async';
|
||||
|
||||
@override
|
||||
bool get isDartCore => _absoluteUri == 'dart:core';
|
||||
bool get isDartCore => _absoluteUri.toString() == 'dart:core';
|
||||
|
||||
/**
|
||||
* If this library is part of the build unit being linked, return the library
|
||||
|
|
|
@ -500,6 +500,10 @@ class _ConstExprBuilder {
|
|||
case UnlinkedExprOperation.ifNull:
|
||||
_pushBinary(TokenType.QUESTION_QUESTION);
|
||||
break;
|
||||
case UnlinkedExprOperation.await:
|
||||
Expression expression = _pop();
|
||||
_push(AstTestFactory.awaitExpression(expression));
|
||||
break;
|
||||
case UnlinkedExprOperation.assignToRef:
|
||||
case UnlinkedExprOperation.assignToProperty:
|
||||
case UnlinkedExprOperation.assignToIndex:
|
||||
|
|
|
@ -66,7 +66,7 @@ abstract class AbstractConstExprSerializer {
|
|||
bool isValidConst = true;
|
||||
|
||||
/**
|
||||
* See [UnlinkedExprBuilder.nmae].
|
||||
* See [UnlinkedExprBuilder.name].
|
||||
*/
|
||||
String name = null;
|
||||
|
||||
|
@ -380,6 +380,10 @@ abstract class AbstractConstExprSerializer {
|
|||
isValidConst = false;
|
||||
_serialize(expr.expression);
|
||||
operations.add(UnlinkedExprOperation.throwException);
|
||||
} else if (expr is AwaitExpression) {
|
||||
isValidConst = false;
|
||||
_serialize(expr.expression);
|
||||
operations.add(UnlinkedExprOperation.await);
|
||||
} else {
|
||||
throw new StateError('Unknown expression type: $expr');
|
||||
}
|
||||
|
|
|
@ -3673,6 +3673,31 @@ abstract class D extends C {
|
|||
checkLibrary('var v = () => 0;');
|
||||
}
|
||||
|
||||
test_initializer_executable_with_return_type_from_closure_await_dynamic() {
|
||||
checkLibrary('var v = (f) async => await f;');
|
||||
}
|
||||
|
||||
test_initializer_executable_with_return_type_from_closure_await_future3_int() {
|
||||
checkLibrary(r'''
|
||||
import 'dart:async';
|
||||
var v = (Future<Future<Future<int>>> f) async => await f;
|
||||
''');
|
||||
}
|
||||
|
||||
test_initializer_executable_with_return_type_from_closure_await_future_int() {
|
||||
checkLibrary(r'''
|
||||
import 'dart:async';
|
||||
var v = (Future<int> f) async => await f;
|
||||
''');
|
||||
}
|
||||
|
||||
test_initializer_executable_with_return_type_from_closure_await_future_noArg() {
|
||||
checkLibrary(r'''
|
||||
import 'dart:async';
|
||||
var v = (Future f) async => await f;
|
||||
''');
|
||||
}
|
||||
|
||||
test_initializer_executable_with_return_type_from_closure_field() {
|
||||
checkLibrary('''
|
||||
class C {
|
||||
|
|
|
@ -1843,6 +1843,26 @@ class C<T> {
|
|||
operators: [UnlinkedExprOperation.pushParameter], strings: ['T']);
|
||||
}
|
||||
|
||||
test_constExpr_functionExpression() {
|
||||
if (skipNonConstInitializers) {
|
||||
return;
|
||||
}
|
||||
UnlinkedVariable variable = serializeVariableText('''
|
||||
import 'dart:async';
|
||||
const v = (f) async => await f;
|
||||
''');
|
||||
_assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
|
||||
isValidConst: false,
|
||||
operators: [
|
||||
UnlinkedExprOperation.pushParameter,
|
||||
UnlinkedExprOperation.await
|
||||
],
|
||||
strings: [
|
||||
'f'
|
||||
],
|
||||
ints: []);
|
||||
}
|
||||
|
||||
test_constExpr_functionExpression_asArgument() {
|
||||
// Even though function expressions are not allowed in constant
|
||||
// declarations, they might occur due to erroneous code, so make sure they
|
||||
|
|
Loading…
Reference in a new issue