@eernst wrote in #51482 (comment)
(Actually, looking at this, I believe initializerExpression should include throw and assignment expressions; but I've never seen any failures because they aren't currently included).
Here's one failure:
|
class AssertAlwaysThrows_Constructor { |
|
Object a; |
|
Object b; |
|
|
|
AssertAlwaysThrows_Constructor( |
|
Object o, Object p, bool Function(Object, Object) f) |
|
: a = o is int ? true : throw 'x', |
|
b = throw 'x', |
|
assert(f(o = p, throw 'x')) { |
|
/*int*/ o; |
|
} |
|
} |
The spec does not appear to support throw expressions in constructor initializer expressions.
Throw expressions are supported by the implementation (actually, throwExpressionWithoutCascade), but not by the spec:
class Foo {
int i = 0;
Foo(int j) : i = throw 0;
}
=== Analyzer ===
Scan errors: 0
Parse errors: 0
<CompilationUnitImpl> [0-55]
┗━ <ClassDeclarationImpl> [0-54]
┣━ 'class' [0-5]
┣━ 'Foo' [6-9]
┣━ '{' [10-11]
┣━ <FieldDeclarationImpl> [14-24]
┃ ┣━ <VariableDeclarationListImpl> [14-23]
┃ ┃ ┣━ <NamedTypeImpl> [14-17]
┃ ┃ ┃ ┗━ 'int' [14-17]
┃ ┃ ┗━ <VariableDeclarationImpl> [18-23]
┃ ┃ ┣━ 'i' [18-19]
┃ ┃ ┣━ '=' [20-21]
┃ ┃ ┗━ <IntegerLiteralImpl> [22-23]
┃ ┃ ┗━ '0' [22-23]
┃ ┗━ ';' [23-24]
┣━ <ConstructorDeclarationImpl> [27-52]
┃ ┣━ <SimpleIdentifierImpl> [27-30]
┃ ┃ ┗━ 'Foo' [27-30]
┃ ┣━ <FormalParameterListImpl> [30-37]
┃ ┃ ┣━ '(' [30-31]
┃ ┃ ┣━ <SimpleFormalParameterImpl> [31-36]
┃ ┃ ┃ ┣━ <NamedTypeImpl> [31-34]
┃ ┃ ┃ ┃ ┗━ 'int' [31-34]
┃ ┃ ┃ ┗━ 'j' [35-36]
┃ ┃ ┗━ ')' [36-37]
┃ ┣━ ':' [38-39]
┃ ┣━ <ConstructorFieldInitializerImpl> [40-51]
┃ ┃ ┣━ <SimpleIdentifierImpl> [40-41]
┃ ┃ ┃ ┗━ 'i' [40-41]
┃ ┃ ┣━ '=' [42-43]
┃ ┃ ┗━ <ThrowExpressionImpl> [44-51]
┃ ┃ ┣━ 'throw' [44-49]
┃ ┃ ┗━ <IntegerLiteralImpl> [50-51]
┃ ┃ ┗━ '0' [50-51]
┃ ┗━ <EmptyFunctionBodyImpl> [51-52]
┃ ┗━ ';' [51-52]
┗━ '}' [53-54]
--------------------------------------------------------------------------------
=== ANTLR ===
Errors of type 1: [[@16,44:48='throw',<78>,3:19] Bad state: , [@16,44:48='throw',<78>,3:19] Bad state: , [@13,38:38=':',<12>,3:13] Bad state: , [@12,36:36=')',<7>,3:11] Bad state: , [@12,36:36=')',<7>,3:11] Bad state: , [@15,42:42='=',<2>,3:17] Bad state: , [@15,42:42='=',<2>,3:17] Bad state: ]
Errors of type 2: []
<startSymbol>
┗━ <libraryDefinition>
┣━ <metadata>
┣━ <topLevelDefinition>
┃ ┗━ <classDeclaration>
┃ ┣━ <classModifiers>
┃ ┣━ 'class'
┃ ┣━ <typeWithParameters>
┃ ┃ ┗━ <typeIdentifier>
┃ ┃ ┗━ 'Foo'
┃ ┣━ '{'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┣━ <declaration>
┃ ┃ ┃ ┣━ <varOrType>
┃ ┃ ┃ ┃ ┗━ <type>
┃ ┃ ┃ ┃ ┗━ <typeNotFunction>
┃ ┃ ┃ ┃ ┗━ <typeNotVoidNotFunction>
┃ ┃ ┃ ┃ ┗━ <typeName>
┃ ┃ ┃ ┃ ┗━ <typeIdentifier>
┃ ┃ ┃ ┃ ┗━ 'int'
┃ ┃ ┃ ┗━ <initializedIdentifierList>
┃ ┃ ┃ ┗━ <initializedIdentifier>
┃ ┃ ┃ ┣━ <identifier>
┃ ┃ ┃ ┃ ┗━ 'i'
┃ ┃ ┃ ┣━ '='
┃ ┃ ┃ ┗━ <expression>
┃ ┃ ┃ ┗━ <conditionalExpression>
┃ ┃ ┃ ┗━ <ifNullExpression>
┃ ┃ ┃ ┗━ <logicalOrExpression>
┃ ┃ ┃ ┗━ <logicalAndExpression>
┃ ┃ ┃ ┗━ <equalityExpression>
┃ ┃ ┃ ┗━ <relationalExpression>
┃ ┃ ┃ ┗━ <bitwiseOrExpression>
┃ ┃ ┃ ┗━ <bitwiseXorExpression>
┃ ┃ ┃ ┗━ <bitwiseAndExpression>
┃ ┃ ┃ ┗━ <shiftExpression>
┃ ┃ ┃ ┗━ <additiveExpression>
┃ ┃ ┃ ┗━ <multiplicativeExpression>
┃ ┃ ┃ ┗━ <unaryExpression>
┃ ┃ ┃ ┗━ <postfixExpression>
┃ ┃ ┃ ┗━ <primary>
┃ ┃ ┃ ┗━ <literal>
┃ ┃ ┃ ┗━ <numericLiteral>
┃ ┃ ┃ ┗━ '0'
┃ ┃ ┗━ ';'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┗━ 'Foo'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┗━ '('
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┗━ 'int'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┣━ 'j'
┃ ┃ ┣━ ')'
┃ ┃ ┗━ ':'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┣━ 'i'
┃ ┃ ┣━ '='
┃ ┃ ┣━ 'throw'
┃ ┃ ┣━ '0'
┃ ┃ ┗━ ';'
┃ ┗━ '}'
┗━ '<EOF>'
Assignment expressions are also supported by the implementation (it even supports cascades), but not by the spec:
class Foo {
int i = 0;
Foo(int j) : i = j *= 0;
}
=== Analyzer ===
Scan errors: 0
Parse errors: 0
<CompilationUnitImpl> [0-54]
┗━ <ClassDeclarationImpl> [0-53]
┣━ 'class' [0-5]
┣━ 'Foo' [6-9]
┣━ '{' [10-11]
┣━ <FieldDeclarationImpl> [14-24]
┃ ┣━ <VariableDeclarationListImpl> [14-23]
┃ ┃ ┣━ <NamedTypeImpl> [14-17]
┃ ┃ ┃ ┗━ 'int' [14-17]
┃ ┃ ┗━ <VariableDeclarationImpl> [18-23]
┃ ┃ ┣━ 'i' [18-19]
┃ ┃ ┣━ '=' [20-21]
┃ ┃ ┗━ <IntegerLiteralImpl> [22-23]
┃ ┃ ┗━ '0' [22-23]
┃ ┗━ ';' [23-24]
┣━ <ConstructorDeclarationImpl> [27-51]
┃ ┣━ <SimpleIdentifierImpl> [27-30]
┃ ┃ ┗━ 'Foo' [27-30]
┃ ┣━ <FormalParameterListImpl> [30-37]
┃ ┃ ┣━ '(' [30-31]
┃ ┃ ┣━ <SimpleFormalParameterImpl> [31-36]
┃ ┃ ┃ ┣━ <NamedTypeImpl> [31-34]
┃ ┃ ┃ ┃ ┗━ 'int' [31-34]
┃ ┃ ┃ ┗━ 'j' [35-36]
┃ ┃ ┗━ ')' [36-37]
┃ ┣━ ':' [38-39]
┃ ┣━ <ConstructorFieldInitializerImpl> [40-50]
┃ ┃ ┣━ <SimpleIdentifierImpl> [40-41]
┃ ┃ ┃ ┗━ 'i' [40-41]
┃ ┃ ┣━ '=' [42-43]
┃ ┃ ┗━ <AssignmentExpressionImpl> [44-50]
┃ ┃ ┣━ <SimpleIdentifierImpl> [44-45]
┃ ┃ ┃ ┗━ 'j' [44-45]
┃ ┃ ┣━ '*=' [46-48]
┃ ┃ ┗━ <IntegerLiteralImpl> [49-50]
┃ ┃ ┗━ '0' [49-50]
┃ ┗━ <EmptyFunctionBodyImpl> [50-51]
┃ ┗━ ';' [50-51]
┗━ '}' [52-53]
--------------------------------------------------------------------------------
=== ANTLR ===
Errors of type 1: [[@17,46:47='*=',<22>,3:21] Bad state: , [@17,46:47='*=',<22>,3:21] Bad state: , [@13,38:38=':',<12>,3:13] Bad state: , [@12,36:36=')',<7>,3:11] Bad state: , [@12,36:36=')',<7>,3:11] Bad state: , [@15,42:42='=',<2>,3:17] Bad state: , [@15,42:42='=',<2>,3:17] Bad state: , [@17,46:47='*=',<22>,3:21] Bad state: , [@17,46:47='*=',<22>,3:21] Bad state: ]
Errors of type 2: []
<startSymbol>
┗━ <libraryDefinition>
┣━ <metadata>
┣━ <topLevelDefinition>
┃ ┗━ <classDeclaration>
┃ ┣━ <classModifiers>
┃ ┣━ 'class'
┃ ┣━ <typeWithParameters>
┃ ┃ ┗━ <typeIdentifier>
┃ ┃ ┗━ 'Foo'
┃ ┣━ '{'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┣━ <declaration>
┃ ┃ ┃ ┣━ <varOrType>
┃ ┃ ┃ ┃ ┗━ <type>
┃ ┃ ┃ ┃ ┗━ <typeNotFunction>
┃ ┃ ┃ ┃ ┗━ <typeNotVoidNotFunction>
┃ ┃ ┃ ┃ ┗━ <typeName>
┃ ┃ ┃ ┃ ┗━ <typeIdentifier>
┃ ┃ ┃ ┃ ┗━ 'int'
┃ ┃ ┃ ┗━ <initializedIdentifierList>
┃ ┃ ┃ ┗━ <initializedIdentifier>
┃ ┃ ┃ ┣━ <identifier>
┃ ┃ ┃ ┃ ┗━ 'i'
┃ ┃ ┃ ┣━ '='
┃ ┃ ┃ ┗━ <expression>
┃ ┃ ┃ ┗━ <conditionalExpression>
┃ ┃ ┃ ┗━ <ifNullExpression>
┃ ┃ ┃ ┗━ <logicalOrExpression>
┃ ┃ ┃ ┗━ <logicalAndExpression>
┃ ┃ ┃ ┗━ <equalityExpression>
┃ ┃ ┃ ┗━ <relationalExpression>
┃ ┃ ┃ ┗━ <bitwiseOrExpression>
┃ ┃ ┃ ┗━ <bitwiseXorExpression>
┃ ┃ ┃ ┗━ <bitwiseAndExpression>
┃ ┃ ┃ ┗━ <shiftExpression>
┃ ┃ ┃ ┗━ <additiveExpression>
┃ ┃ ┃ ┗━ <multiplicativeExpression>
┃ ┃ ┃ ┗━ <unaryExpression>
┃ ┃ ┃ ┗━ <postfixExpression>
┃ ┃ ┃ ┗━ <primary>
┃ ┃ ┃ ┗━ <literal>
┃ ┃ ┃ ┗━ <numericLiteral>
┃ ┃ ┃ ┗━ '0'
┃ ┃ ┗━ ';'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┗━ 'Foo'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┗━ '('
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┗━ 'int'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┣━ 'j'
┃ ┃ ┣━ ')'
┃ ┃ ┗━ ':'
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┣━ 'i'
┃ ┃ ┗━ '='
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┣━ <metadata>
┃ ┣━ <classMemberDeclaration>
┃ ┃ ┣━ 'j'
┃ ┃ ┣━ '*='
┃ ┃ ┣━ '0'
┃ ┃ ┗━ ';'
┃ ┗━ '}'
┗━ '<EOF>'
The spec also supports some expressions that the implementation does not support, see #11509 for that.
@eernst wrote in #51482 (comment)
Here's one failure:
sdk/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/promotion_in_dead_code.dart
Lines 50 to 61 in 408e486
The spec does not appear to support throw expressions in constructor initializer expressions.
Throw expressions are supported by the implementation (actually,
throwExpressionWithoutCascade), but not by the spec:Assignment expressions are also supported by the implementation (it even supports cascades), but not by the spec:
The spec also supports some expressions that the implementation does not support, see #11509 for that.