diff --git a/pkg/_fe_analyzer_shared/test/constants/data/errors.dart b/pkg/_fe_analyzer_shared/test/constants/data/errors.dart index c25cead7cfb..b2026dcffba 100644 --- a/pkg/_fe_analyzer_shared/test/constants/data/errors.dart +++ b/pkg/_fe_analyzer_shared/test/constants/data/errors.dart @@ -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 = diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart index cb0c0ff5ded..256c06156cc 100644 --- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart +++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart @@ -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); diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart index 003c3b0f4a1..877c7132e2b 100644 --- a/pkg/analyzer/test/generated/error_suppression_test.dart +++ b/pkg/analyzer/test/generated/error_suppression_test.dart @@ -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; +''', + [], + ); + } } diff --git a/pkg/analyzer/test/id_tests/constant_test.dart b/pkg/analyzer/test/id_tests/constant_test.dart index e249afe2873..7d6e44f58b9 100644 --- a/pkg/analyzer/test/id_tests/constant_test.dart +++ b/pkg/analyzer/test/id_tests/constant_test.dart @@ -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 { @override DataInterpreter get dataValidator => const StringDataInterpreter(); + @override + bool get supportsErrors => true; + + @override + String computeErrorData(TestConfig config, TestingData testingData, Id id, + List 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> actualMap) { diff --git a/pkg/dart_internal/analysis_options.yaml b/pkg/dart_internal/analysis_options.yaml index 1a46de2ee05..edcd64e558e 100644 --- a/pkg/dart_internal/analysis_options.yaml +++ b/pkg/dart_internal/analysis_options.yaml @@ -1,3 +1,5 @@ analyzer: + errors: + import_internal_library: ignore strong-mode: implicit-casts: false diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt index 8b137891791..80acd97a3f7 100644 --- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt +++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt @@ -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'.