8de8a1c226
They are all errors now. Change-Id: If48d38e38e845fd5b5a950dd5514bf1cbbce03d8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155880 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
366 lines
10 KiB
Dart
366 lines
10 KiB
Dart
// Copyright (c) 2014, 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 'dart:async';
|
|
|
|
import 'package:analyzer/dart/analysis/declared_variables.dart';
|
|
import 'package:analyzer/src/error/codes.dart';
|
|
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
|
|
|
|
import '../src/dart/resolution/driver_resolution.dart';
|
|
|
|
class CompileTimeErrorCodeTestBase extends DriverResolutionTest {
|
|
test_bug_23176() async {
|
|
await assertErrorsInCode('''
|
|
class A {
|
|
const A([x]);
|
|
}
|
|
class B {
|
|
dynamic @A(const A()) x;
|
|
}
|
|
''', [
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 40, 7),
|
|
error(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 40, 7),
|
|
error(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 62, 1),
|
|
]);
|
|
}
|
|
|
|
test_builtInIdentifierAsType_formalParameter_field() async {
|
|
await assertErrorsInCode(r'''
|
|
class A {
|
|
var x;
|
|
A(static this.x);
|
|
}
|
|
''', [
|
|
error(ParserErrorCode.EXTRANEOUS_MODIFIER, 23, 6),
|
|
]);
|
|
}
|
|
|
|
test_builtInIdentifierAsType_formalParameter_simple() async {
|
|
await assertErrorsInCode(r'''
|
|
f(static x) {
|
|
}
|
|
''', [
|
|
error(ParserErrorCode.EXTRANEOUS_MODIFIER, 2, 6),
|
|
]);
|
|
}
|
|
|
|
test_builtInIdentifierAsType_variableDeclaration() async {
|
|
await assertErrorsInCode(r'''
|
|
f() {
|
|
typedef x;
|
|
}
|
|
''', [
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 8, 7),
|
|
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 8, 7),
|
|
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 16, 1),
|
|
]);
|
|
}
|
|
|
|
test_consistentCaseExpressionTypes_dynamic() async {
|
|
// Even though A.S and S have a static type of "dynamic", we should see
|
|
// that they match 'abc', because they are constant strings.
|
|
await assertNoErrorsInCode(r'''
|
|
class A {
|
|
static const S = 'A.S';
|
|
}
|
|
|
|
const S = 'S';
|
|
|
|
foo(var p) {
|
|
switch (p) {
|
|
case S:
|
|
break;
|
|
case A.S:
|
|
break;
|
|
case 'abc':
|
|
break;
|
|
}
|
|
}
|
|
''');
|
|
}
|
|
|
|
test_constConstructor_redirect_generic() async {
|
|
await assertNoErrorsInCode(r'''
|
|
class A<T> {
|
|
const A(T value) : this._(value);
|
|
const A._(T value) : value = value;
|
|
final T value;
|
|
}
|
|
|
|
void main(){
|
|
const A<int>(1);
|
|
}
|
|
''');
|
|
}
|
|
|
|
test_constEvalThrowsException() async {
|
|
await assertErrorsInCode(r'''
|
|
class C {
|
|
const C();
|
|
}
|
|
f() { return const C(); }
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, 0, 0),
|
|
]);
|
|
}
|
|
|
|
test_constEvalThrowsException_divisionByZero() async {
|
|
await assertErrorsInCode('''
|
|
const C = 1 ~/ 0;
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE, 10, 6),
|
|
]);
|
|
}
|
|
|
|
test_constEvalTypeInt_binary() async {
|
|
await _check_constEvalTypeBoolOrInt_binary("a ^ ''");
|
|
await _check_constEvalTypeBoolOrInt_binary("a & ''");
|
|
await _check_constEvalTypeBoolOrInt_binary("a | ''");
|
|
await _check_constEvalTypeInt_binary("a >> ''");
|
|
await _check_constEvalTypeInt_binary("a << ''");
|
|
}
|
|
|
|
test_constEvalTypeNum_binary() async {
|
|
await _check_constEvalTypeNum_binary("a + ''");
|
|
await _check_constEvalTypeNum_binary("a - ''");
|
|
await _check_constEvalTypeNum_binary("a * ''");
|
|
await _check_constEvalTypeNum_binary("a / ''");
|
|
await _check_constEvalTypeNum_binary("a ~/ ''");
|
|
await _check_constEvalTypeNum_binary("a > ''");
|
|
await _check_constEvalTypeNum_binary("a < ''");
|
|
await _check_constEvalTypeNum_binary("a >= ''");
|
|
await _check_constEvalTypeNum_binary("a <= ''");
|
|
await _check_constEvalTypeNum_binary("a % ''");
|
|
}
|
|
|
|
test_constWithNonConstantArgument_annotation() async {
|
|
await assertErrorsInCode(r'''
|
|
class A {
|
|
const A(int p);
|
|
}
|
|
var v = 42;
|
|
@A(v)
|
|
main() {
|
|
}
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 45, 1),
|
|
]);
|
|
}
|
|
|
|
test_constWithNonConstantArgument_classShadowedBySetter() async {
|
|
await assertErrorsInCode(r'''
|
|
class Annotation {
|
|
const Annotation(Object obj);
|
|
}
|
|
|
|
class Bar {}
|
|
|
|
class Foo {
|
|
@Annotation(Bar)
|
|
set Bar(int value) {}
|
|
}
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 94, 3),
|
|
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 94, 3),
|
|
]);
|
|
}
|
|
|
|
test_constWithNonConstantArgument_instanceCreation() async {
|
|
await assertErrorsInCode(r'''
|
|
class A {
|
|
const A(a);
|
|
}
|
|
f(p) { return const A(p); }
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 48, 1),
|
|
]);
|
|
}
|
|
|
|
test_fromEnvironment_bool_badArgs() async {
|
|
await assertErrorsInCode(r'''
|
|
var b1 = const bool.fromEnvironment(1);
|
|
var b2 = const bool.fromEnvironment('x', defaultValue: 1);
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 9, 29),
|
|
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 36, 1),
|
|
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 49, 48),
|
|
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 81, 15),
|
|
]);
|
|
}
|
|
|
|
test_fromEnvironment_bool_badDefault_whenDefined() async {
|
|
// The type of the defaultValue needs to be correct even when the default
|
|
// value isn't used (because the variable is defined in the environment).
|
|
driver.declaredVariables = DeclaredVariables.fromMap({'x': 'true'});
|
|
await assertErrorsInCode('''
|
|
var b = const bool.fromEnvironment('x', defaultValue: 1);
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 8, 48),
|
|
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 40, 15),
|
|
]);
|
|
}
|
|
|
|
test_genericFunctionTypeArgument_inference_function() async {
|
|
await assertErrorsInCode(r'''
|
|
T f<T>(T t) => null;
|
|
main() { f(<S>(S s) => s); }
|
|
''', [
|
|
error(CompileTimeErrorCode.COULD_NOT_INFER, 30, 1),
|
|
]);
|
|
}
|
|
|
|
test_genericFunctionTypeArgument_inference_functionType() async {
|
|
await assertErrorsInCode(r'''
|
|
T Function<T>(T) f;
|
|
main() { f(<S>(S s) => s); }
|
|
''', [
|
|
error(CompileTimeErrorCode.COULD_NOT_INFER, 29, 1),
|
|
]);
|
|
}
|
|
|
|
test_genericFunctionTypeArgument_inference_method() async {
|
|
await assertErrorsInCode(r'''
|
|
class C {
|
|
T f<T>(T t) => null;
|
|
}
|
|
main() { new C().f(<S>(S s) => s); }
|
|
''', [
|
|
error(CompileTimeErrorCode.COULD_NOT_INFER, 52, 1),
|
|
]);
|
|
}
|
|
|
|
test_genericFunctionTypedParameter() async {
|
|
var code = '''
|
|
void g(T f<T>(T x)) {}
|
|
''';
|
|
await assertNoErrorsInCode(code);
|
|
}
|
|
|
|
test_length_of_erroneous_constant() async {
|
|
// Attempting to compute the length of constant that couldn't be evaluated
|
|
// (due to an error) should not crash the analyzer (see dartbug.com/23383)
|
|
await assertErrorsInCode('''
|
|
const int i = (1 ? 'alpha' : 'beta').length;
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 14,
|
|
29),
|
|
error(CompileTimeErrorCode.NON_BOOL_CONDITION, 15, 1),
|
|
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL, 15, 1),
|
|
]);
|
|
}
|
|
|
|
test_nonConstMapAsExpressionStatement_begin() async {
|
|
// TODO(danrubel): Consider improving recovery
|
|
await assertErrorsInCode(r'''
|
|
f() {
|
|
{'a' : 0, 'b' : 1}.length;
|
|
}
|
|
''', [
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 9, 3),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 13, 1),
|
|
error(ParserErrorCode.MISSING_IDENTIFIER, 13, 1),
|
|
error(ParserErrorCode.UNEXPECTED_TOKEN, 13, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 15, 1),
|
|
error(ParserErrorCode.UNEXPECTED_TOKEN, 16, 1),
|
|
error(ParserErrorCode.MISSING_IDENTIFIER, 16, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 18, 3),
|
|
error(ParserErrorCode.UNEXPECTED_TOKEN, 22, 1),
|
|
error(ParserErrorCode.MISSING_IDENTIFIER, 22, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 22, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 24, 1),
|
|
error(ParserErrorCode.MISSING_IDENTIFIER, 26, 1),
|
|
]);
|
|
}
|
|
|
|
test_nonConstMapAsExpressionStatement_only() async {
|
|
// TODO(danrubel): Consider improving recovery
|
|
await assertErrorsInCode(r'''
|
|
f() {
|
|
{'a' : 0, 'b' : 1};
|
|
}
|
|
''', [
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 9, 3),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 13, 1),
|
|
error(ParserErrorCode.MISSING_IDENTIFIER, 13, 1),
|
|
error(ParserErrorCode.UNEXPECTED_TOKEN, 13, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 15, 1),
|
|
error(ParserErrorCode.UNEXPECTED_TOKEN, 16, 1),
|
|
error(ParserErrorCode.MISSING_IDENTIFIER, 16, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 18, 3),
|
|
error(ParserErrorCode.UNEXPECTED_TOKEN, 22, 1),
|
|
error(ParserErrorCode.MISSING_IDENTIFIER, 22, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 22, 1),
|
|
error(ParserErrorCode.EXPECTED_TOKEN, 24, 1),
|
|
]);
|
|
}
|
|
|
|
test_nonConstValueInInitializer_instanceCreation_inDifferentFile() async {
|
|
newFile('/test/lib/a.dart', content: '''
|
|
import 'b.dart';
|
|
const v = const MyClass();
|
|
''');
|
|
await assertErrorsInCode('''
|
|
class MyClass {
|
|
const MyClass([p = foo]);
|
|
}
|
|
''', [
|
|
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 37, 3),
|
|
error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 37, 3),
|
|
]);
|
|
}
|
|
|
|
test_symbol_constructor_badArgs() async {
|
|
await assertErrorsInCode(r'''
|
|
var s1 = const Symbol('3');
|
|
var s2 = const Symbol(3);
|
|
var s3 = const Symbol();
|
|
var s4 = const Symbol('x', 'y');
|
|
var s5 = const Symbol('x', foo: 'x');
|
|
''', [
|
|
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 9, 17),
|
|
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 37, 15),
|
|
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 50, 1),
|
|
error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 75, 2),
|
|
error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 100, 10),
|
|
error(CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER, 139, 3),
|
|
]);
|
|
}
|
|
|
|
Future<void> _check_constEvalTypeBoolOrInt_binary(String expr) async {
|
|
await assertErrorsInCode('''
|
|
const int a = 0;
|
|
const _ = $expr;
|
|
''', [
|
|
error(HintCode.UNUSED_ELEMENT, 23, 1),
|
|
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT, 27, 6),
|
|
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 31, 2),
|
|
]);
|
|
}
|
|
|
|
Future<void> _check_constEvalTypeInt_binary(String expr) async {
|
|
await assertErrorsInCode('''
|
|
const int a = 0;
|
|
const _ = $expr;
|
|
''', [
|
|
error(HintCode.UNUSED_ELEMENT, 23, 1),
|
|
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT, 27, 6),
|
|
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 31, 2),
|
|
]);
|
|
}
|
|
|
|
Future<void> _check_constEvalTypeNum_binary(String expr) async {
|
|
await assertErrorsInCode('''
|
|
const num a = 0;
|
|
const _ = $expr;
|
|
''', [
|
|
error(HintCode.UNUSED_ELEMENT, 23, 1),
|
|
error(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM, 27, 6),
|
|
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 31, 2),
|
|
]);
|
|
}
|
|
}
|