mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 10:18:13 +00:00
Test logical-and in variable declaration, report REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT.
Change-Id: I7fcffea3b591fbe3a181a8bb8a8a461d18ec3d64 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/273340 Reviewed-by: Samuel Rawlins <srawlins@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
cdf5aa216e
commit
46bffdabb1
|
@ -946,6 +946,8 @@ CompileTimeErrorCode.REDIRECT_TO_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER:
|
|||
status: needsEvaluation
|
||||
CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION:
|
||||
status: needsEvaluation
|
||||
CompileTimeErrorCode.REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT:
|
||||
status: needsEvaluation
|
||||
CompileTimeErrorCode.RELATIONAL_PATTERN_OPERATOR_RETURN_TYPE_NOT_ASSIGNABLE_TO_BOOL:
|
||||
status: noFix
|
||||
CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH:
|
||||
|
|
|
@ -1120,8 +1120,14 @@ class BinaryPatternImpl extends DartPatternImpl implements BinaryPattern {
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitBinaryPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.analyzeLogicalPatternSchema(
|
||||
leftOperand,
|
||||
rightOperand,
|
||||
isAnd: operator.type == TokenType.AMPERSAND ||
|
||||
operator.type == TokenType.AMPERSAND_AMPERSAND,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
@ -2810,8 +2816,9 @@ class ConstantPatternImpl extends DartPatternImpl implements ConstantPattern {
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitConstantPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.analyzeConstantPatternSchema();
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
@ -2819,7 +2826,8 @@ class ConstantPatternImpl extends DartPatternImpl implements ConstantPattern {
|
|||
DartType matchedType,
|
||||
SharedMatchContext context,
|
||||
) {
|
||||
resolverVisitor.analyzeExpression(expression, matchedType);
|
||||
resolverVisitor.analyzeConstantPattern(
|
||||
matchedType, context, this, expression);
|
||||
expression = resolverVisitor.popRewrite()!;
|
||||
}
|
||||
|
||||
|
@ -10985,8 +10993,9 @@ class RelationalPatternImpl extends DartPatternImpl
|
|||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitRelationalPattern(this);
|
||||
|
||||
@override
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) =>
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
DartType computePatternSchema(ResolverVisitor resolverVisitor) {
|
||||
return resolverVisitor.analyzeRelationalPatternSchema();
|
||||
}
|
||||
|
||||
@override
|
||||
void resolvePattern(
|
||||
|
|
|
@ -40,9 +40,7 @@ class SharedTypeAnalyzerErrors
|
|||
}
|
||||
|
||||
@override
|
||||
void assertInErrorRecovery() {
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
}
|
||||
void assertInErrorRecovery() {}
|
||||
|
||||
@override
|
||||
void caseExpressionTypeMismatch(
|
||||
|
@ -129,7 +127,10 @@ class SharedTypeAnalyzerErrors
|
|||
|
||||
@override
|
||||
void refutablePatternInIrrefutableContext(AstNode pattern, AstNode context) {
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
_errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT,
|
||||
pattern,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -4004,6 +4004,15 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
|
|||
hasPublishedDocs: true,
|
||||
);
|
||||
|
||||
static const CompileTimeErrorCode REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT =
|
||||
CompileTimeErrorCode(
|
||||
'REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT',
|
||||
"Refutable patterns can't be used in an irrefutable context.",
|
||||
correctionMessage:
|
||||
"Try using an if-case, a 'switch' statement, or a 'switch' expression "
|
||||
"instead.",
|
||||
);
|
||||
|
||||
static const CompileTimeErrorCode
|
||||
RELATIONAL_PATTERN_OPERATOR_RETURN_TYPE_NOT_ASSIGNABLE_TO_BOOL =
|
||||
CompileTimeErrorCode(
|
||||
|
|
|
@ -401,6 +401,7 @@ const List<ErrorCode> errorCodeValues = [
|
|||
CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR,
|
||||
CompileTimeErrorCode.REDIRECT_TO_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER,
|
||||
CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION,
|
||||
CompileTimeErrorCode.REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT,
|
||||
CompileTimeErrorCode
|
||||
.RELATIONAL_PATTERN_OPERATOR_RETURN_TYPE_NOT_ASSIGNABLE_TO_BOOL,
|
||||
CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH,
|
||||
|
|
|
@ -12269,6 +12269,9 @@ CompileTimeErrorCode:
|
|||
print(x);
|
||||
}
|
||||
```
|
||||
REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT:
|
||||
problemMessage: Refutable patterns can't be used in an irrefutable context.
|
||||
correctionMessage: Try using an if-case, a 'switch' statement, or a 'switch' expression instead.
|
||||
RELATIONAL_PATTERN_OPERATOR_RETURN_TYPE_NOT_ASSIGNABLE_TO_BOOL:
|
||||
problemMessage: The return type of operators used in relational patterns must be assignable to 'bool'.
|
||||
correctionMessage: Try updating the operator declaration to return 'bool'.
|
||||
|
|
|
@ -75,6 +75,38 @@ BinaryPattern
|
|||
''');
|
||||
}
|
||||
|
||||
test_logicalAnd_variableDeclaration() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f() {
|
||||
var (a && b) = 0;
|
||||
}
|
||||
''');
|
||||
final node = findNode.singlePatternVariableDeclarationStatement;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclarationStatement
|
||||
declaration: PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: BinaryPattern
|
||||
leftOperand: VariablePattern
|
||||
name: a
|
||||
declaredElement: hasImplicitType a@18
|
||||
type: int
|
||||
operator: &&
|
||||
rightOperand: VariablePattern
|
||||
name: b
|
||||
declaredElement: hasImplicitType b@23
|
||||
type: int
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
semicolon: ;
|
||||
''');
|
||||
}
|
||||
|
||||
test_logicalOr_ifCase() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(x) {
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(RefutablePatternInIrrefutableContextTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class RefutablePatternInIrrefutableContextTest
|
||||
extends PubPackageResolutionTest {
|
||||
test_declaration_constantPattern() async {
|
||||
await assertErrorsInCode(r'''
|
||||
void f() {
|
||||
var (0) = 0;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT, 18, 1),
|
||||
]);
|
||||
|
||||
var node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
''');
|
||||
}
|
||||
|
||||
test_declaration_logicalOrPattern() async {
|
||||
await assertErrorsInCode(r'''
|
||||
void f() {
|
||||
var (_ || _) = 0;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT, 18, 6),
|
||||
]);
|
||||
|
||||
var node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: BinaryPattern
|
||||
leftOperand: VariablePattern
|
||||
name: _
|
||||
operator: ||
|
||||
rightOperand: VariablePattern
|
||||
name: _
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
''');
|
||||
}
|
||||
|
||||
test_declaration_nullCheckPattern() async {
|
||||
await assertErrorsInCode(r'''
|
||||
void f() {
|
||||
var (_?) = 0;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT, 18, 2),
|
||||
]);
|
||||
|
||||
var node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: PostfixPattern
|
||||
operand: VariablePattern
|
||||
name: _
|
||||
operator: ?
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
''');
|
||||
}
|
||||
|
||||
test_declaration_relationalPattern() async {
|
||||
await assertErrorsInCode(r'''
|
||||
void f() {
|
||||
var (> 0) = 0;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.REFUTABLE_PATTERN_IN_IRREFUTABLE_CONTEXT, 18, 3),
|
||||
]);
|
||||
|
||||
var node = findNode.singlePatternVariableDeclaration;
|
||||
assertResolvedNodeText(node, r'''
|
||||
PatternVariableDeclaration
|
||||
keyword: var
|
||||
pattern: ParenthesizedPattern
|
||||
leftParenthesis: (
|
||||
pattern: RelationalPattern
|
||||
operator: >
|
||||
operand: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
element: dart:core::@class::num::@method::>
|
||||
rightParenthesis: )
|
||||
equals: =
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
''');
|
||||
}
|
||||
}
|
|
@ -652,6 +652,8 @@ import 'redirect_to_type_alias_expands_to_type_parameter_test.dart'
|
|||
as redirect_to_type_alias_expands_to_type_parameter;
|
||||
import 'referenced_before_declaration_test.dart'
|
||||
as referenced_before_declaration;
|
||||
import 'refutable_pattern_in_irrefutable_context_test.dart'
|
||||
as refutable_pattern_in_irrefutable_context;
|
||||
import 'relational_pattern_operator_return_type_not_assignable_to_bool_test.dart'
|
||||
as relational_pattern_operator_return_type_not_assignable_to_bool;
|
||||
import 'rethrow_outside_catch_test.dart' as rethrow_outside_catch;
|
||||
|
@ -1241,6 +1243,7 @@ main() {
|
|||
redirect_to_non_const_constructor.main();
|
||||
redirect_to_type_alias_expands_to_type_parameter.main();
|
||||
referenced_before_declaration.main();
|
||||
refutable_pattern_in_irrefutable_context.main();
|
||||
relational_pattern_operator_return_type_not_assignable_to_bool.main();
|
||||
rethrow_outside_catch.main();
|
||||
return_in_generative_constructor.main();
|
||||
|
|
Loading…
Reference in a new issue