mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 14:59:41 +00:00
analyzer: Do not allow errors to be ignored inline. Fixes #27218
Change-Id: If37dabba3ec18a9f79f44c4ea38d6920a4013019 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/140142 Commit-Queue: Samuel Rawlins <srawlins@google.com> Reviewed-by: Paul Berry <paulberry@google.com> Reviewed-by: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
parent
830bfd8886
commit
2c420267b7
|
@ -2,10 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// ignore_for_file: const_initialized_with_non_constant_value
|
||||
|
||||
// TODO(paulberry): Support testing errors in analyzer id testing.
|
||||
|
||||
String method() => 'foo';
|
||||
|
||||
const String string0 =
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:analyzer/dart/analysis/features.dart';
|
|||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/visitor.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/diagnostic/diagnostic.dart';
|
||||
import 'package:analyzer/error/error.dart';
|
||||
import 'package:analyzer/error/listener.dart';
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
|
@ -411,12 +412,39 @@ class LibraryAnalyzer {
|
|||
LineInfo lineInfo = _fileToLineInfo[file];
|
||||
|
||||
bool isIgnored(AnalysisError error) {
|
||||
var code = error.errorCode;
|
||||
// Don't allow error severity issues to be ignored.
|
||||
if (error.severity == Severity.error) {
|
||||
bool privileged = false;
|
||||
|
||||
if (code == StaticTypeWarningCode.UNDEFINED_FUNCTION ||
|
||||
code == StaticTypeWarningCode.UNDEFINED_PREFIXED_NAME) {
|
||||
// Special case a small number of errors in Flutter code which are
|
||||
// ignored. The erroneous code is found in a conditionally imported
|
||||
// library, which uses a special version of the "dart:ui" library
|
||||
// which the Analyzer does not use during analysis. See
|
||||
// https://github.com/flutter/flutter/issues/52899.
|
||||
if (file.path.contains('flutter')) {
|
||||
privileged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (code == CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY &&
|
||||
file.path.contains('tests/compiler/dart2js')) {
|
||||
// Special case the dart2js language tests. Some of these import
|
||||
// various internal libraries.
|
||||
privileged = true;
|
||||
}
|
||||
|
||||
if (!privileged) return false;
|
||||
}
|
||||
|
||||
int errorLine = lineInfo.getLocation(error.offset).lineNumber;
|
||||
String name = error.errorCode.name.toLowerCase();
|
||||
String name = code.name.toLowerCase();
|
||||
if (ignoreInfo.ignoredAt(name, errorLine)) {
|
||||
return true;
|
||||
}
|
||||
String uniqueName = error.errorCode.uniqueName;
|
||||
String uniqueName = code.uniqueName;
|
||||
int period = uniqueName.indexOf('.');
|
||||
if (period >= 0) {
|
||||
uniqueName = uniqueName.substring(period + 1);
|
||||
|
|
|
@ -16,86 +16,102 @@ main() {
|
|||
|
||||
@reflectiveTest
|
||||
class ErrorSuppressionTest extends DriverResolutionTest with PackageMixin {
|
||||
String get ignoredCode => 'const_initialized_with_non_constant_value';
|
||||
String get ignoredCode => 'unused_element';
|
||||
|
||||
test_does_not_ignore_errors() async {
|
||||
await assertErrorsInCode('''
|
||||
int x = ''; // ignore: invalid_assignment
|
||||
''', [
|
||||
error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
|
||||
]);
|
||||
}
|
||||
|
||||
test_error_cannot_be_ignored() async {
|
||||
await assertErrorsInCode('''
|
||||
// ignore: unused_import, undefined_function
|
||||
f() => g();
|
||||
''', [
|
||||
error(StaticTypeWarningCode.UNDEFINED_FUNCTION, 52, 1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_error_code_mismatch() async {
|
||||
await assertErrorsInCode('''
|
||||
// ignore: $ignoredCode
|
||||
int x = '';
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
int _y = 0; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
''', [
|
||||
error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 61, 2),
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 75,
|
||||
1),
|
||||
error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 34, 2),
|
||||
error(HintCode.UNUSED_ELEMENT, 42, 2),
|
||||
]);
|
||||
}
|
||||
|
||||
test_ignore_first() async {
|
||||
await assertErrorsInCode('''
|
||||
// ignore: invalid_assignment
|
||||
int x = '';
|
||||
// ignore: unnecessary_cast
|
||||
int x = (0 as int);
|
||||
// ... but no ignore here ...
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 88,
|
||||
1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_ignore_first_trailing() async {
|
||||
await assertErrorsInCode('''
|
||||
int x = ''; // ignore: invalid_assignment
|
||||
int x = (0 as int); // ignore: unnecessary_cast
|
||||
// ... but no ignore here ...
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 88,
|
||||
1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_ignore_for_file() async {
|
||||
await assertErrorsInCode('''
|
||||
int x = ''; //INVALID_ASSIGNMENT
|
||||
int x = (0 as int); //UNNECESSARY_CAST
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
// ignore_for_file: invalid_assignment
|
||||
// ignore_for_file: unnecessary_cast
|
||||
''', [
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 49,
|
||||
1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_ignore_for_file_whitespace_variant() async {
|
||||
await assertNoErrorsInCode('''
|
||||
//ignore_for_file: $ignoredCode , invalid_assignment
|
||||
int x = ''; //INVALID_ASSIGNMENT
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
//ignore_for_file: $ignoredCode , unnecessary_cast
|
||||
int x = (0 as int); //UNNECESSARY_CAST
|
||||
String _foo; //UNUSED_ELEMENT
|
||||
''');
|
||||
}
|
||||
|
||||
test_ignore_only_trailing() async {
|
||||
await assertNoErrorsInCode('''
|
||||
int x = ''; // ignore: invalid_assignment
|
||||
int x = (0 as int); // ignore: unnecessary_cast
|
||||
''');
|
||||
}
|
||||
|
||||
test_ignore_second() async {
|
||||
await assertErrorsInCode('''
|
||||
//INVALID_ASSIGNMENT
|
||||
int x = '';
|
||||
//UNNECESSARY_CAST
|
||||
int x = (0 as int);
|
||||
// ignore: $ignoredCode
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
String _foo; //UNUSED_ELEMENT
|
||||
''', [
|
||||
error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
|
||||
error(HintCode.UNNECESSARY_CAST, 28, 8),
|
||||
]);
|
||||
}
|
||||
|
||||
test_ignore_second_trailing() async {
|
||||
await assertErrorsInCode('''
|
||||
//INVALID_ASSIGNMENT
|
||||
int x = '';
|
||||
const y = x; // ignore: $ignoredCode
|
||||
//UNNECESSARY_CAST
|
||||
int x = (0 as int);
|
||||
String _foo; // ignore: $ignoredCode
|
||||
''', [
|
||||
error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
|
||||
error(HintCode.UNNECESSARY_CAST, 28, 8),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -113,7 +129,7 @@ int x = f();
|
|||
|
||||
test_ignore_upper_case() async {
|
||||
await assertNoErrorsInCode('''
|
||||
int x = ''; // ignore: INVALID_ASSIGNMENT
|
||||
int x = (0 as int); // ignore: UNNECESSARY_CAST
|
||||
''');
|
||||
}
|
||||
|
||||
|
@ -152,78 +168,111 @@ String y = 3; //INVALID_ASSIGNMENT
|
|||
|
||||
test_multiple_comments() async {
|
||||
await assertErrorsInCode('''
|
||||
int x = ''; //This is the first comment...
|
||||
int x = (0 as int); //This is the first comment...
|
||||
// ignore: $ignoredCode
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
String _foo; //UNUSED_ELEMENT
|
||||
''', [
|
||||
error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
|
||||
error(HintCode.UNNECESSARY_CAST, 9, 8),
|
||||
]);
|
||||
}
|
||||
|
||||
test_multiple_ignore_for_files() async {
|
||||
await assertNoErrorsInCode('''
|
||||
int x = ''; //INVALID_ASSIGNMENT
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
// ignore_for_file: invalid_assignment,$ignoredCode
|
||||
int x = (0 as int); //UNNECESSARY_CAST
|
||||
String _foo; //UNUSED_ELEMENT
|
||||
// ignore_for_file: unnecessary_cast,$ignoredCode
|
||||
''');
|
||||
}
|
||||
|
||||
test_multiple_ignores() async {
|
||||
await assertNoErrorsInCode('''
|
||||
int x = 3;
|
||||
// ignore: invalid_assignment, $ignoredCode
|
||||
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
// ignore: unnecessary_cast, $ignoredCode
|
||||
int _y = x as int; //UNNECESSARY_CAST, UNUSED_ELEMENT
|
||||
''');
|
||||
}
|
||||
|
||||
test_multiple_ignores_trailing() async {
|
||||
await assertNoErrorsInCode('''
|
||||
int x = 3;
|
||||
const String y = x; // ignore: invalid_assignment, $ignoredCode
|
||||
int _y = x as int; // ignore: unnecessary_cast, $ignoredCode
|
||||
''');
|
||||
}
|
||||
|
||||
test_multiple_ignores_whitespace_variant_1() async {
|
||||
await assertNoErrorsInCode('''
|
||||
int x = 3;
|
||||
//ignore:invalid_assignment,$ignoredCode
|
||||
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
//ignore:unnecessary_cast,$ignoredCode
|
||||
int _y = x as int; //UNNECESSARY_CAST, UNUSED_ELEMENT
|
||||
''');
|
||||
}
|
||||
|
||||
test_multiple_ignores_whitespace_variant_2() async {
|
||||
await assertNoErrorsInCode('''
|
||||
int x = 3;
|
||||
//ignore: invalid_assignment,$ignoredCode
|
||||
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
//ignore: unnecessary_cast,$ignoredCode
|
||||
int _y = x as int; //UNNECESSARY_CAST, UNUSED_ELEMENT
|
||||
''');
|
||||
}
|
||||
|
||||
test_multiple_ignores_whitespace_variant_3() async {
|
||||
await assertNoErrorsInCode('''
|
||||
int x = 3;
|
||||
// ignore: invalid_assignment,$ignoredCode
|
||||
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
// ignore: unnecessary_cast,$ignoredCode
|
||||
int _y = x as int; //UNNECESSARY_CAST, UNUSED_ELEMENT
|
||||
''');
|
||||
}
|
||||
|
||||
test_no_ignores() async {
|
||||
await assertErrorsInCode('''
|
||||
int x = ''; //INVALID_ASSIGNMENT
|
||||
int x = ''; //INVALID_ASSIGNMENT
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
''', [
|
||||
error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 43,
|
||||
1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_trailing_not_above() async {
|
||||
await assertErrorsInCode('''
|
||||
int x = ''; // ignore: invalid_assignment
|
||||
int y = '';
|
||||
int x = (0 as int); // ignore: unnecessary_cast
|
||||
int y = (0 as int);
|
||||
''', [
|
||||
error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 50, 2),
|
||||
error(HintCode.UNNECESSARY_CAST, 57, 8),
|
||||
]);
|
||||
}
|
||||
|
||||
test_undefined_function_within_flutter_can_be_ignored() async {
|
||||
await assertErrorsInFile(
|
||||
'/workspace/flutterlib/flutter.dart',
|
||||
'''
|
||||
// ignore: undefined_function
|
||||
f() => g();
|
||||
''',
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
test_undefined_function_within_flutter_without_ignore() async {
|
||||
await assertErrorsInFile(
|
||||
'/workspace/flutterlib/flutter.dart',
|
||||
'''
|
||||
f() => g();
|
||||
''',
|
||||
[error(StaticTypeWarningCode.UNDEFINED_FUNCTION, 7, 1)],
|
||||
);
|
||||
}
|
||||
|
||||
test_undefined_prefixed_name_within_flutter_can_be_ignored() async {
|
||||
await assertErrorsInFile(
|
||||
'/workspace/flutterlib/flutter.dart',
|
||||
'''
|
||||
import 'dart:collection' as c;
|
||||
// ignore: undefined_prefixed_name
|
||||
f() => c.g;
|
||||
''',
|
||||
[],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ import 'package:analyzer/dart/constant/value.dart';
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer/error/error.dart';
|
||||
import 'package:analyzer/src/dart/analysis/testing_data.dart';
|
||||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:analyzer/src/util/ast_data_extractor.dart';
|
||||
|
||||
import '../util/id_testing_helper.dart';
|
||||
|
@ -35,6 +37,18 @@ class ConstantsDataComputer extends DataComputer<String> {
|
|||
@override
|
||||
DataInterpreter<String> get dataValidator => const StringDataInterpreter();
|
||||
|
||||
@override
|
||||
bool get supportsErrors => true;
|
||||
|
||||
@override
|
||||
String computeErrorData(TestConfig config, TestingData testingData, Id id,
|
||||
List<AnalysisError> errors) {
|
||||
var errorCodes = errors.map((e) => e.errorCode).where((errorCode) =>
|
||||
errorCode !=
|
||||
CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
|
||||
return errorCodes.isNotEmpty ? errorCodes.join(',') : null;
|
||||
}
|
||||
|
||||
@override
|
||||
void computeUnitData(TestingData testingData, CompilationUnit unit,
|
||||
Map<Id, ActualData<String>> actualMap) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
analyzer:
|
||||
errors:
|
||||
import_internal_library: ignore
|
||||
strong-mode:
|
||||
implicit-casts: false
|
||||
|
|
|
@ -1 +1,8 @@
|
|||
|
||||
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3716|5|94|Const constructors can't throw exceptions.
|
||||
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7902|5|97|Const constructors can't throw exceptions.
|
||||
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|940|5|95|Const constructors can't throw exceptions.
|
||||
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|973|5|94|Const constructors can't throw exceptions.
|
||||
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3714|3|5|Only redirecting factory constructors can be declared to be 'const'.
|
||||
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7900|3|5|Only redirecting factory constructors can be declared to be 'const'.
|
||||
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|938|3|5|Only redirecting factory constructors can be declared to be 'const'.
|
||||
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|971|3|5|Only redirecting factory constructors can be declared to be 'const'.
|
||||
|
|
Loading…
Reference in a new issue