Check exact type for set literals (issue 35742)

Change-Id: Icce758b13536171dd20201e52ecae8ecda39a336
Reviewed-on: https://dart-review.googlesource.com/c/91166
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Brian Wilkerson 2019-01-25 21:09:42 +00:00 committed by commit-bot@chromium.org
parent eadf9679f3
commit 6fae43b8af
3 changed files with 97 additions and 0 deletions

View file

@ -578,6 +578,30 @@ class CodeChecker extends RecursiveAstVisitor {
node.visitChildren(this);
}
@override
void visitSetLiteral(SetLiteral node) {
DartType type = DynamicTypeImpl.instance;
if (node.typeArguments != null) {
NodeList<TypeAnnotation> targs = node.typeArguments.arguments;
if (targs.length > 0) {
type = targs[0].type;
}
} else {
DartType staticType = node.staticType;
if (staticType is InterfaceType) {
List<DartType> typeArguments = staticType.typeArguments;
if (typeArguments != null && typeArguments.length > 0) {
type = typeArguments[0];
}
}
}
NodeList<Expression> elements = node.elements;
for (int i = 0; i < elements.length; i++) {
checkArgument(elements[i], type);
}
super.visitSetLiteral(node);
}
@override
void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
var element = node.staticElement;

View file

@ -0,0 +1,71 @@
// Copyright (c) 2019, 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 '../../generated/resolver_test_case.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(InvalidCastNewExprTest);
});
}
@reflectiveTest
class InvalidCastNewExprTest extends ResolverTestCase {
@override
List<String> get enabledExperiments => ['set-literals'];
@override
bool get enableNewAnalysisDriver => true;
test_listLiteral_const() async {
await assertErrorsInCode(r'''
const c = <B>[A()];
class A {
const A();
}
class B extends A {
const B();
}
''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
}
test_listLiteral_nonConst() async {
await assertErrorsInCode(r'''
var c = <B>[A()];
class A {
const A();
}
class B extends A {
const B();
}
''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
}
test_setLiteral_const() async {
await assertErrorsInCode(r'''
const c = <B>{A()};
class A {
const A();
}
class B extends A {
const B();
}
''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
}
test_setLiteral_nonConst() async {
await assertErrorsInCode(r'''
var c = <B>{A()};
class A {
const A();
}
class B extends A {
const B();
}
''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
}
}

View file

@ -9,6 +9,7 @@ import 'can_be_null_after_null_aware_test.dart' as can_be_null_after_null_aware;
import 'deprecated_member_use_test.dart' as deprecated_member_use;
import 'division_optimization_test.dart' as division_optimization;
import 'invalid_assignment_test.dart' as invalid_assignment;
import 'invalid_cast_new_expr_test.dart' as invalid_cast_new_expr;
import 'invalid_required_param_test.dart' as invalid_required_param;
import 'undefined_getter.dart' as undefined_getter;
import 'unnecessary_cast_test.dart' as unnecessary_cast;
@ -25,6 +26,7 @@ main() {
deprecated_member_use.main();
division_optimization.main();
invalid_assignment.main();
invalid_cast_new_expr.main();
invalid_required_param.main();
undefined_getter.main();
unnecessary_cast.main();