blob: 8afcd5b80077ee6b3b81702d2946396fe82d3990 [file] [log] [blame]
// 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(StaticTypeWarningCode.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),
]);
}
}