From 9185294e7a80943b05be50ea3305173217da62cc Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Tue, 25 Sep 2018 18:51:04 +0000 Subject: [PATCH] Reland: Implement inheritance/override checks from the spec. Relands https://dart-review.googlesource.com/c/sdk/+/76061 Was reverted in https://dart-review.googlesource.com/c/sdk/+/76301 The difference with the original CL is that we don't look into superclass and mixins of mixed-in for concrete members. This reduces the number of errors in Flutter codebase to 1. R=brianwilkerson@google.com Bug: https://github.com/dart-lang/sdk/issues/34392 Change-Id: I86256b598d116439194cbaf4d09b4f72013d6563 Reviewed-on: https://dart-review.googlesource.com/76340 Reviewed-by: Brian Wilkerson Commit-Queue: Konstantin Shcheglov --- pkg/analyzer/lib/error/error.dart | 15 +- .../src/dart/analysis/library_analyzer.dart | 23 +- pkg/analyzer/lib/src/dart/element/type.dart | 42 +- .../dart/resolver/inheritance_manager.dart | 66 +-- pkg/analyzer/lib/src/error/codes.dart | 267 +++--------- .../lib/src/error/inheritance_override.dart | 384 ++++++++++++++++++ .../lib/src/fasta/error_converter.dart | 2 +- .../lib/src/generated/error_verifier.dart | 2 +- pkg/analyzer/lib/src/task/dart.dart | 9 + pkg/analyzer/lib/src/task/strong/checker.dart | 347 +--------------- .../compile_time_error_code_test.dart | 44 +- .../test/generated/non_hint_code_test.dart | 10 +- .../generated/static_warning_code_test.dart | 201 +++------ .../test/generated/strong_mode_test.dart | 8 +- .../test/src/dart/resolution/class_test.dart | 20 +- .../test/src/dart/resolution/mixin_test.dart | 90 ++-- .../src/summary/top_level_inference_test.dart | 2 +- pkg/analyzer/test/src/task/options_test.dart | 3 - .../test/src/task/strong/checker_test.dart | 323 +++++++-------- .../src/task/strong/inferred_type_test.dart | 16 +- pkg/analyzer_cli/test/strong_mode_test.dart | 2 +- tests/language_2/language_2_analyzer.status | 6 +- tests/language_2/language_2_dartdevc.status | 6 +- tests/language_2/regress_34392_test.dart | 19 + 24 files changed, 856 insertions(+), 1051 deletions(-) create mode 100644 pkg/analyzer/lib/src/error/inheritance_override.dart create mode 100644 tests/language_2/regress_34392_test.dart diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart index 7292017b75896..24350132f9927 100644 --- a/pkg/analyzer/lib/error/error.dart +++ b/pkg/analyzer/lib/error/error.dart @@ -145,6 +145,8 @@ const List errorCodeValues = const [ CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, @@ -164,6 +166,7 @@ const List errorCodeValues = const [ CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR, CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER, CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, + CompileTimeErrorCode.INVALID_OVERRIDE, CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP, @@ -532,7 +535,6 @@ const List errorCodeValues = const [ StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, StaticTypeWarningCode.INVALID_ASSIGNMENT, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, @@ -591,14 +593,6 @@ const List errorCodeValues = const [ StaticWarningCode.FUNCTION_WITHOUT_CALL, StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, StaticWarningCode.IMPORT_OF_NON_LIBRARY, - StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, - StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, - StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, - StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE, - StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, - StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE, - StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS, - StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND, StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED, StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL, StaticWarningCode.INVALID_OVERRIDE_NAMED, @@ -674,9 +668,6 @@ const List errorCodeValues = const [ StrongModeCode.INVALID_CAST_METHOD, StrongModeCode.INVALID_CAST_FUNCTION, StrongModeCode.INVALID_FIELD_OVERRIDE, - StrongModeCode.INVALID_METHOD_OVERRIDE, - StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_BASE, - StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_MIXIN, StrongModeCode.INVALID_PARAMETER_DECLARATION, StrongModeCode.INVALID_SUPER_INVOCATION, StrongModeCode.NO_DEFAULT_BOUNDS, diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart index 3de1ee3bd3fb4..6fe57fe9e5dc0 100644 --- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart +++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart @@ -19,6 +19,7 @@ import 'package:analyzer/src/dart/constant/utilities.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/handle.dart'; import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/error/inheritance_override.dart'; import 'package:analyzer/src/error/pending_error.dart'; import 'package:analyzer/src/generated/declaration_resolver.dart'; import 'package:analyzer/src/generated/engine.dart'; @@ -294,14 +295,13 @@ class LibraryAnalyzer { RecordingErrorListener errorListener = _getErrorListener(file); AnalysisOptionsImpl options = _analysisOptions as AnalysisOptionsImpl; - CodeChecker checker = new CodeChecker( - _typeProvider, - new StrongTypeSystemImpl(_typeProvider, - implicitCasts: options.implicitCasts, - declarationCasts: options.declarationCasts, - nonnullableTypes: options.nonnullableTypes), - errorListener, - options); + var typeSystem = new StrongTypeSystemImpl(_typeProvider, + implicitCasts: options.implicitCasts, + declarationCasts: options.declarationCasts, + nonnullableTypes: options.nonnullableTypes); + + CodeChecker checker = + new CodeChecker(_typeProvider, typeSystem, errorListener, options); checker.visitCompilationUnit(unit); ErrorReporter errorReporter = _getErrorReporter(file); @@ -316,6 +316,13 @@ class LibraryAnalyzer { // _computeConstantErrors(errorReporter, unit); + // + // Compute inheritance and override errors. + // + var inheritanceOverrideVerifier = + new InheritanceOverrideVerifier(typeSystem, errorReporter); + inheritanceOverrideVerifier.verifyUnit(unit); + // // Use the ErrorVerifier to compute errors. // diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart index 617f5a5161289..1a9ce46bbca3a 100644 --- a/pkg/analyzer/lib/src/dart/element/type.dart +++ b/pkg/analyzer/lib/src/dart/element/type.dart @@ -1766,13 +1766,19 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { } ExecutableElement lookUpInheritedMember(String name, LibraryElement library, - {bool concrete: false, int stopMixinIndex, bool setter: false}) { + {bool concrete: false, + int startMixinIndex, + bool setter: false, + bool thisType: false}) { HashSet visitedClasses = new HashSet(); + /// TODO(scheglov) Remove [includeSupers]. It is used only to work around + /// the problem with Flutter code base (using old super-mixins). ExecutableElement lookUpImpl(InterfaceTypeImpl type, {bool acceptAbstract: false, bool includeType: true, - int stopMixinIndex}) { + bool includeSupers: true, + int startMixinIndex}) { if (type == null || !visitedClasses.add(type.element)) { return null; } @@ -1792,14 +1798,18 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { } } - var mixins = type.mixins; - for (var i = 0; i < mixins.length; i++) { - if (stopMixinIndex != null && i >= stopMixinIndex) { - break; - } - var result = lookUpImpl(mixins[i], acceptAbstract: acceptAbstract); - if (result != null) { - return result; + if (includeSupers) { + var mixins = type.mixins; + startMixinIndex ??= mixins.length; + for (var i = startMixinIndex - 1; i >= 0; i--) { + var result = lookUpImpl( + mixins[i], + acceptAbstract: acceptAbstract, + includeSupers: false, + ); + if (result != null) { + return result; + } } } @@ -1814,10 +1824,16 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { } } - return lookUpImpl(type.superclass, acceptAbstract: acceptAbstract); + if (includeSupers) { + return lookUpImpl(type.superclass, acceptAbstract: acceptAbstract); + } + + return null; } if (element.isMixin) { + // TODO(scheglov) We should choose the most specific signature. + // Not just the first signature. for (InterfaceType constraint in superclassConstraints) { var result = lookUpImpl(constraint, acceptAbstract: true); if (result != null) { @@ -1828,8 +1844,8 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { } else { return lookUpImpl( this, - includeType: false, - stopMixinIndex: stopMixinIndex, + includeType: thisType, + startMixinIndex: startMixinIndex, ); } } diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart index db3945b11b8eb..2a4d371a00492 100644 --- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart +++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart @@ -15,7 +15,6 @@ import 'package:analyzer/src/dart/ast/token.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/member.dart'; import 'package:analyzer/src/dart/element/type.dart'; -import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer/src/generated/type_system.dart'; import 'package:analyzer/src/generated/utilities_dart.dart'; @@ -716,34 +715,10 @@ class InheritanceManager { } } - /** - * This method is used to report errors on when they are found computing inheritance information. - * See [ErrorVerifier.checkForInconsistentMethodInheritance] to see where these generated - * error codes are reported back into the analysis engine. - * - * @param classElt the location of the source for which the exception occurred - * @param offset the offset of the location of the error - * @param length the length of the location of the error - * @param errorCode the error code to be associated with this error - * @param arguments the arguments used to build the error message - */ - void _reportError( - ClassElement classElt, ErrorCode errorCode, List arguments) { - if (ignoreErrors) { - return; - } - HashSet errorSet = _errorsInClassElement.putIfAbsent( - classElt, () => new HashSet()); - errorSet.add(new AnalysisError(classElt.source, classElt.nameOffset, - classElt.nameLength, errorCode, arguments)); - } - /** * Given the set of methods defined by classes above [classElt] in the class hierarchy, * apply the appropriate inheritance rules to determine those methods inherited by or overridden - * by [classElt]. Also report static warnings - * [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE] and - * [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD] if appropriate. + * by [classElt]. * * @param classElt the class element to query. * @param unionMap a mapping from method name to the set of unique (in terms of signature) methods @@ -838,38 +813,7 @@ class InheritanceManager { // resultMap[key] = elements[subtypesOfAllOtherTypesIndexes[0]]; } else { - if (subtypesOfAllOtherTypesIndexes.isEmpty) { - // - // Determine if the current class has a method or accessor with - // the member name, if it does then then this class does not - // "inherit" from any of the supertypes. See issue 16134. - // - bool classHasMember = false; - if (allMethods) { - classHasMember = classElt.getMethod(key) != null; - } else { - List accessors = classElt.accessors; - for (int i = 0; i < accessors.length; i++) { - if (accessors[i].name == key) { - classHasMember = true; - } - } - } - // - // Example: class A inherited only 2 method named 'm'. - // One has the function type '() -> int' and one has the function - // type '() -> String'. Since neither is a subtype of the other, - // we create a warning, and have this class inherit nothing. - // - if (!classHasMember) { - String firstTwoFunctionTypesStr = - "${executableElementTypes[0]}, ${executableElementTypes[1]}"; - _reportError( - classElt, - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, - [key, firstTwoFunctionTypesStr]); - } - } else { + if (!subtypesOfAllOtherTypesIndexes.isEmpty) { // // Example: class A inherits 2 methods named 'm'. // One has the function type '(int) -> dynamic' and one has the @@ -896,12 +840,6 @@ class InheritanceManager { resultMap[key] = mergedExecutableElement; } } - } else { - _reportError( - classElt, - StaticWarningCode - .INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, - [key]); } } }); diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart index 37b838cbf89cc..b1d42a6eadb75 100644 --- a/pkg/analyzer/lib/src/error/codes.dart +++ b/pkg/analyzer/lib/src/error/codes.dart @@ -1260,6 +1260,46 @@ class CompileTimeErrorCode extends ErrorCode { const CompileTimeErrorCode('INCONSISTENT_CASE_EXPRESSION_TYPES', "Case expressions must have the same types, '{0}' isn't a '{1}'."); + /** + * If a class declaration does not have a member declaration with a + * particular name, but some super-interfaces do have a member with that + * name, it's a compile-time error if there is no signature among the + * super-interfaces that is a valid override of all the other super-interface + * signatures with the same name. That "most specific" signature becomes the + * signature of the class's interface. + * + * Parameters: + * 0: the name of the instance member with inconsistent inheritance. + * 1: the list of all inherited signatures for this member. + */ + static const CompileTimeErrorCode INCONSISTENT_INHERITANCE = + const CompileTimeErrorCode('INCONSISTENT_INHERITANCE', + "Superinterfaces don't have a valid override for '{0}': {1}.", + correction: + "Try adding an explicit override that is consistent with all " + "of the inherited members."); + + /** + * 11.1.1 Inheritance and Overriding. Let `I` be the implicit interface of a + * class `C` declared in library `L`. `I` inherits all members of + * `inherited(I, L)` and `I` overrides `m'` if `m' ∈ overrides(I, L)`. It is + * a compile-time error if `m` is a method and `m'` is a getter, or if `m` + * is a getter and `m'` is a method. + * + * Parameters: + * 0: the name of the the instance member with inconsistent inheritance. + * 1: the name of the superinterface that declares the name as a getter. + * 2: the name of the superinterface that declares the name as a method. + */ + static const CompileTimeErrorCode INCONSISTENT_INHERITANCE_GETTER_AND_METHOD = + const CompileTimeErrorCode( + 'INCONSISTENT_INHERITANCE_GETTER_AND_METHOD', + "'{0}' is inherited as a getter (from '{1}') and also a " + "method (from '{2}').", + correction: + "Try adjusting the supertypes of this class to remove the " + "inconsistency."); + /** * 7.6.1 Generative Constructors: Let k be a generative constructor. It * is a compile-time error if k's initializer list contains an @@ -1487,6 +1527,26 @@ class CompileTimeErrorCode extends ErrorCode { correction: "Try using a generic function type (returnType 'Function(' parameters ')')."); + /** + * If a class declaration has a member declaration, the signature of that + * member declaration becomes the signature in the interface. It's a + * compile-time error if that signature is not a valid override of all + * super-interface member signatures with the same name. (Not just the + * members of the immediate super-interfaces, but all of them. For + * non-covariant parameters, it's sufficient to check just the immediate + * super-interfaces). + * + * Parameters: + * 0: the name of the declared member that is not a valid override. + * 1: the name of the interface that declares the member. + * 2: the type of the declared member in the interface. + * 3. the name of the interface with the overridden member. + * 4. the type of the overridden member. + */ + static const CompileTimeErrorCode INVALID_OVERRIDE = + const CompileTimeErrorCode('INVALID_OVERRIDE', + "'{1}.{0}' ('{2}') isn't a valid override of '{3}.{0}' ('{4}')."); + /** * 12.10 This: It is a compile-time error if this appears in a top-level * function or variable initializer, in a factory constructor, or in a static @@ -2795,41 +2855,6 @@ class StaticTypeWarningCode extends ErrorCode { correction: "Try fixing the return type of the function, or " "removing the modifier 'sync*' from the function body."); - /** - * 8.1.1 Inheritance and Overriding: However, if the above rules would cause - * multiple members m1, …, mk with the - * same name n that would be inherited (because identically named - * members existed in several superinterfaces) then at most one member is - * inherited. - * - * If the static types T1, …, Tk of the - * members m1, …, mk are not identical, - * then there must be a member mx such that Tx - * <: Ti, 1 <= x <= k for all i, 1 <= i <= - * k, or a static type warning occurs. The member that is inherited is - * mx, if it exists; otherwise: - * * Let numberOfPositionals(f) denote the number of positional - * parameters of a function f, and let - * numberOfRequiredParams(f) denote the number of required - * parameters of a function f. Furthermore, let s denote the - * set of all named parameters of the m1, …, - * mk. Then let - * * h = max(numberOfPositionals(mi)), - * * r = min(numberOfRequiredParams(mi)), for all i, 1 <= - * i <= k. If r <= h then I has a method named n, - * with r required parameters of type dynamic, h - * positional parameters of type dynamic, named parameters s - * of type dynamic and return type dynamic. - * * Otherwise none of the members m1, …, - * mk is inherited. - */ - static const StaticTypeWarningCode INCONSISTENT_METHOD_INHERITANCE = - const StaticTypeWarningCode('INCONSISTENT_METHOD_INHERITANCE', - "Inconsistent declarations of '{0}' are inherited from {1}.", - correction: - "Try adjusting the supertypes of this class to remove the " - "inconsistency."); - /** * 12.15.1 Ordinary Invocation: It is a static type warning if T does * not have an accessible (3.2) instance member named m. @@ -3806,158 +3831,6 @@ class StaticWarningCode extends ErrorCode { "The imported library '{0}' can't have a part-of directive.", correction: "Try importing the library that the part is a part of."); - /** - * 11.1.1 Inheritance and Overriding. Let `I` be the implicit interface of a - * class `C` declared in library `L`. `I` inherits all members of - * `inherited(I, L)` and `I` overrides `m'` if `m' ∈ overrides(I, L)`. It is - * a compile-time error if `m` is a method and `m'` is a getter, or if `m` - * is a getter and `m'` is a method. - */ - static const StaticWarningCode - INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD = - const StaticWarningCode( - 'INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD', - "'{0}' is inherited as a getter and also a method.", - correction: - "Try adjusting the supertypes of this class to remove the " - "inconsistency."); - - /** - * 7.2 Getters: It is a static warning if a getter m1 overrides a - * getter m2 and the type of m1 is not a subtype of the type of - * m2. - * - * Parameters: - * 0: the name of the actual return type - * 1: the name of the expected return type, not assignable to the actual - * return type - * 2: the name of the class where the overridden getter is declared - * - * See [INVALID_METHOD_OVERRIDE_RETURN_TYPE]. - */ - static const StaticWarningCode INVALID_GETTER_OVERRIDE_RETURN_TYPE = - const StaticWarningCode( - 'INVALID_GETTER_OVERRIDE_RETURN_TYPE', - "The return type '{0}' isn't assignable to '{1}' as required by the " - "getter it is overriding from '{2}'.", - correction: - "Try changing the return types so that they are compatible."); - - /** - * 7.1 Instance Methods: It is a static warning if an instance method - * m1 overrides an instance method m2 and the type of m1 - * is not a subtype of the type of m2. - * - * Parameters: - * 0: the name of the actual parameter type - * 1: the name of the expected parameter type, not assignable to the actual - * parameter type - * 2: the name of the class where the overridden method is declared - */ - static const StaticWarningCode INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE = - const StaticWarningCode( - 'INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE', - "The parameter type '{0}' isn't assignable to '{1}' as required by " - "the method it is overriding from '{2}'.", - correction: - "Try changing the parameter types so that they are compatible."); - - /** - * Generic Method DEP: number of type parameters must match. - * - * - * Parameters: - * 0: the number of type parameters in the method - * 1: the number of type parameters in the overridden method - * 2: the name of the class where the overridden method is declared - */ - static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS = - const StaticWarningCode( - 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS', - "The method has {0} type parameters, but it is overriding a method " - "with {1} type parameters from '{2}'.", - correction: - "Try changing the number of type parameters so that they are the same."); - - /** - * Generic Method DEP: bounds of type parameters must be compatible. - * - * - * Parameters: - * 0: the type parameter name - * 1: the type parameter bound - * 2: the overridden type parameter name - * 3: the overridden type parameter bound - * 4: the name of the class where the overridden method is declared - */ - static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND = - const StaticWarningCode( - 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND', - "The type parameter '{0}' extends '{1}', but that is stricter than " - "'{2}' extends '{3}' in the overridden method from '{4}'.", - correction: - "Try changing the bounds on the type parameters so that they are compatible."); - - /** - * 7.1 Instance Methods: It is a static warning if an instance method - * m1 overrides an instance method m2 and the type of m1 - * is not a subtype of the type of m2. - * - * Parameters: - * 0: the name of the actual parameter type - * 1: the name of the expected parameter type, not assignable to the actual - * parameter type - * 2: the name of the class where the overridden method is declared - * See [INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]. - */ - static const StaticWarningCode INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE = - const StaticWarningCode( - 'INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE', - "The parameter type '{0}' isn't assignable to '{1}' as required by " - "the method it is overriding from '{2}'.", - correction: - "Try changing the parameter types so that they are compatible."); - - /** - * 7.1 Instance Methods: It is a static warning if an instance method - * m1 overrides an instance method m2 and the type of m1 - * is not a subtype of the type of m2. - * - * Parameters: - * 0: the name of the actual parameter type - * 1: the name of the expected parameter type, not assignable to the actual - * parameter type - * 2: the name of the class where the overridden method is declared - */ - static const StaticWarningCode INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE = - const StaticWarningCode( - 'INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE', - "The parameter type '{0}' isn't assignable to '{1}' as required by " - "the method it is overriding from '{2}'.", - correction: - "Try changing the parameter types so that they are compatible."); - - /** - * 7.1 Instance Methods: It is a static warning if an instance method - * m1 overrides an instance method m2 and the type of m1 - * is not a subtype of the type of m2. - * - * Parameters: - * 0: the name of the actual return type - * 1: the name of the expected return type, not assignable to the actual - * return type - * 2: the name of the class where the overridden method is declared - * - * See [INVALID_GETTER_OVERRIDE_RETURN_TYPE]. - */ - static const StaticWarningCode INVALID_METHOD_OVERRIDE_RETURN_TYPE = - const StaticWarningCode( - 'INVALID_METHOD_OVERRIDE_RETURN_TYPE', - "The return type '{0}' isn't assignable to '{1}' as required by the " - "method it is overriding from '{2}'.", - correction: - "Try changing the return types so that they are compatible."); - /** * 7.1 Instance Methods: It is a static warning if an instance method * m1 overrides an instance member m2, the signature of @@ -4712,9 +4585,6 @@ class StrongModeCode extends ErrorCode { static const String _implicitCastCorrection = "Try adding an explicit cast to '{1}' or improving the type of '{0}'."; - static const String _invalidOverrideMessage = - "The type of '{0}.{1}' ('{2}') isn't a subtype of '{3}.{1}' ('{4}')."; - /** * This is appended to the end of an error message about implicit dynamic. * @@ -4830,23 +4700,6 @@ class StrongModeCode extends ErrorCode { static const StrongModeCode DYNAMIC_INVOKE = const StrongModeCode( ErrorType.HINT, 'DYNAMIC_INVOKE', "'{0}' requires a dynamic invoke."); - static const StrongModeCode INVALID_METHOD_OVERRIDE = const StrongModeCode( - ErrorType.COMPILE_TIME_ERROR, - 'INVALID_METHOD_OVERRIDE', - "Invalid override. $_invalidOverrideMessage"); - - static const StrongModeCode INVALID_METHOD_OVERRIDE_FROM_BASE = - const StrongModeCode( - ErrorType.COMPILE_TIME_ERROR, - 'INVALID_METHOD_OVERRIDE_FROM_BASE', - "Base class introduces an invalid override. $_invalidOverrideMessage"); - - static const StrongModeCode INVALID_METHOD_OVERRIDE_FROM_MIXIN = - const StrongModeCode( - ErrorType.COMPILE_TIME_ERROR, - 'INVALID_METHOD_OVERRIDE_FROM_MIXIN', - "Mixin introduces an invalid override. $_invalidOverrideMessage"); - static const StrongModeCode INVALID_FIELD_OVERRIDE = const StrongModeCode( ErrorType.COMPILE_TIME_ERROR, 'INVALID_FIELD_OVERRIDE', diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart new file mode 100644 index 0000000000000..1d48cf7403674 --- /dev/null +++ b/pkg/analyzer/lib/src/error/inheritance_override.dart @@ -0,0 +1,384 @@ +// Copyright (c) 2018, 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/analyzer.dart'; +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/error/listener.dart'; +import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/type.dart'; +import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/generated/type_system.dart'; + +class InheritanceOverrideVerifier { + final StrongTypeSystemImpl _typeSystem; + final ErrorReporter _reporter; + + /// Cached instance interfaces for [InterfaceType]. + final Map _interfaces = {}; + + InheritanceOverrideVerifier(this._typeSystem, this._reporter); + + void verifyUnit(CompilationUnit unit) { + for (var declaration in unit.declarations) { + if (declaration is ClassDeclaration) { + _verifyClass(declaration.name, + withClause: declaration.withClause, members: declaration.members); + } else if (declaration is ClassTypeAlias) { + _verifyClass(declaration.name, withClause: declaration.withClause); + } else if (declaration is MixinDeclaration) { + _verifyClass(declaration.name, members: declaration.members); + } + } + } + + /// Check that the given [member] is a valid override of the corresponding + /// instance members in each of [allSuperinterfaces]. + void _checkDeclaredMember( + List allSuperinterfaces, + AstNode node, + ExecutableElement member, + ) { + if (member == null) return; + if (member.isStatic) return; + + var name = member.name; + for (var supertype in allSuperinterfaces) { + var superMember = _getInstanceMember(supertype, name); + if (superMember != null && superMember.isAccessibleIn(member.library)) { + // The case when members have different kinds is reported in verifier. + if (member.kind != superMember.kind) { + continue; + } + + if (!_typeSystem.isOverrideSubtypeOf(member.type, superMember.type)) { + _reporter.reportErrorForNode( + CompileTimeErrorCode.INVALID_OVERRIDE, + node, + [ + name, + member.enclosingElement.name, + member.type.displayName, + superMember.enclosingElement.name, + superMember.type.displayName + ], + ); + } + } + } + } + + /// Check that instance members of [type] are valid overrides of the + /// corresponding instance members in each of [allSuperinterfaces]. + void _checkDeclaredMembers( + List allSuperinterfaces, + AstNode node, + InterfaceTypeImpl type, + ) { + for (var method in type.methods) { + _checkDeclaredMember(allSuperinterfaces, node, method); + } + for (var accessor in type.accessors) { + _checkDeclaredMember(allSuperinterfaces, node, accessor); + } + } + + /// Return the instance member given the [name], defined in the [type], + /// or `null` if the [type] does not define a member with the [name], or + /// if it is not an instance member. + ExecutableElement _getInstanceMember(InterfaceType type, String name) { + ExecutableElement result; + if (name.endsWith('=')) { + name = name.substring(0, name.length - 1); + result = type.getSetter(name); + } else { + result = type.getMethod(name) ?? type.getGetter(name); + } + if (result != null && result.isStatic) { + result = null; + } + return result; + } + + /// Return the interface of the given [type], for the [consumerLibrary]. + _Interface _getInterface(InterfaceType type, LibraryElement consumerLibrary) { + if (type == null) return new _Interface({}, []); + + var result = _interfaces[type]; + if (result != null) return result; + + var map = {}; + var conflicts = <_Conflict>[]; + _interfaces[type] = new _Interface(map, conflicts); + + // If a class declaration has a member declaration, the signature of that + // member declaration becomes the signature in the interface. + { + void addTypeMember(ExecutableElement member) { + if (member.isAccessibleIn(consumerLibrary) && !member.isStatic) { + map[member.name] = member.type; + } + } + + type.methods.forEach(addTypeMember); + type.accessors.forEach(addTypeMember); + } + + var inheritedCandidates = >{}; + void addSuperinterfaceMember(String name, FunctionType candidate) { + // If name is in the [map], then it is defined in the [type] itself. + // Don't consider candidates from direct superinterfaces. + // The version defined in the type might be invalid, we check elsewhere. + if (map.containsKey(name)) return; + + var candidates = inheritedCandidates[name]; + if (candidates == null) { + candidates = []; + inheritedCandidates[name] = candidates; + } + candidates.add(candidate); + } + + var library = type.element.library; + void addSuperinterfaceMembers(InterfaceType superinterface) { + _getInterface(superinterface, library) + .map + .forEach(addSuperinterfaceMember); + } + + // Fill candidates for each instance name. + addSuperinterfaceMembers(type.superclass); + type.superclassConstraints.forEach(addSuperinterfaceMembers); + type.mixins.forEach(addSuperinterfaceMembers); + type.interfaces.forEach(addSuperinterfaceMembers); + + // If a class declaration does not have a member declaration with a + // particular name, but some super-interfaces do have a member with that + // name, it's a compile-time error if there is no signature among the + // super-interfaces that is a valid override of all the other + // super-interface signatures with the same name. That "most specific" + // signature becomes the signature of the class's interface. + for (var name in inheritedCandidates.keys) { + var candidates = inheritedCandidates[name]; + + bool allGetters = true; + bool allMethods = true; + bool allSetters = true; + for (var candidate in candidates) { + var kind = candidate.element.kind; + if (kind != ElementKind.GETTER) { + allGetters = false; + } + if (kind != ElementKind.METHOD) { + allMethods = false; + } + if (kind != ElementKind.SETTER) { + allSetters = false; + } + } + + if (allSetters) { + // OK, setters don't conflict with anything. + } else if (!(allGetters || allMethods)) { + FunctionType getterType; + FunctionType methodType; + for (var candidate in candidates) { + var kind = candidate.element.kind; + if (kind == ElementKind.GETTER) { + getterType ??= candidate; + } + if (kind == ElementKind.METHOD) { + methodType ??= candidate; + } + } + conflicts.add(new _Conflict(name, candidates, getterType, methodType)); + continue; + } + + FunctionType validOverride; + for (var i = 0; i < candidates.length; i++) { + validOverride = candidates[i]; + for (var j = 0; j < candidates.length; j++) { + var candidate = candidates[j]; + if (!_typeSystem.isOverrideSubtypeOf(validOverride, candidate)) { + validOverride = null; + break; + } + } + if (validOverride != null) { + break; + } + } + + if (validOverride != null) { + map[name] = validOverride; + } else { + conflicts.add(new _Conflict(name, candidates)); + } + } + + return new _Interface(map, conflicts); + } + + void _reportInconsistentInheritance(AstNode node, _Conflict conflict) { + var name = conflict.name; + + if (conflict.getter != null && conflict.method != null) { + _reporter.reportErrorForNode( + CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, + node, + [ + name, + conflict.getter.element.enclosingElement.name, + conflict.method.element.enclosingElement.name + ], + ); + } else { + var candidatesStr = conflict.candidates.map((candidate) { + var className = candidate.element.enclosingElement.name; + return '$className.$name (${candidate.displayName})'; + }).join(', '); + + _reporter.reportErrorForNode( + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + node, + [name, candidatesStr], + ); + } + } + + void _verifyClass(SimpleIdentifier classNameNode, + {List members: const [], WithClause withClause}) { + ClassElement element = classNameNode.staticElement; + LibraryElement library = element.library; + InterfaceTypeImpl type = element.type; + + var allSuperinterfaces = []; + + // Add all superinterfaces of the direct supertype. + if (type.superclass != null) { + ClassElementImpl.collectAllSupertypes( + allSuperinterfaces, type.superclass, null); + } + + // Each mixin in `class C extends S with M0, M1, M2 {}` is equivalent to: + // class S&M0 extends S { ...members of M0... } + // class S&M1 extends S&M0 { ...members of M1... } + // class S&M2 extends S&M1 { ...members of M2... } + // class C extends S&M2 { ...members of C... } + // So, we need to check members of each mixin against superinterfaces + // of `S`, and superinterfaces of all previous mixins. + var mixinNodes = withClause?.mixinTypes; + var mixinTypes = type.mixins; + for (var i = 0; i < mixinTypes.length; i++) { + _checkDeclaredMembers(allSuperinterfaces, mixinNodes[i], mixinTypes[i]); + ClassElementImpl.collectAllSupertypes( + allSuperinterfaces, mixinTypes[i], null); + } + + // Add all superinterfaces of the direct class interfaces. + for (var interface in type.interfaces) { + ClassElementImpl.collectAllSupertypes( + allSuperinterfaces, interface, null); + } + + // Check the members if the class itself, against all the previously + // collected superinterfaces of the supertype, mixins, and interfaces. + for (var member in members) { + if (member is FieldDeclaration) { + var fieldList = member.fields; + for (var field in fieldList.variables) { + FieldElement fieldElement = field.declaredElement; + _checkDeclaredMember( + allSuperinterfaces, fieldList, fieldElement.getter); + _checkDeclaredMember( + allSuperinterfaces, fieldList, fieldElement.setter); + } + } else if (member is MethodDeclaration) { + _checkDeclaredMember( + allSuperinterfaces, member, member.declaredElement); + } + } + + // Compute the interface of the class. + var interfaceMembers = _getInterface(type, element.library); + + // Report conflicts between direct superinterfaces of the class. + for (var conflict in interfaceMembers.conflicts) { + _reportInconsistentInheritance(classNameNode, conflict); + } + + // TODO(scheglov) isMixin must be also isAbstract. + if (!element.isAbstract && !element.isMixin) { + for (var name in interfaceMembers.map.keys) { + var concreteElement = type.lookUpInheritedMember(name, library, + concrete: true, thisType: true, setter: name.endsWith('=')); + + // TODO(scheglov) handle here instead of ErrorVerifier? + if (concreteElement == null) { + continue; + } + // TODO(scheglov) Why InterfaceType even returns statics? + if (concreteElement.isStatic) { + continue; + } + + var concreteType = concreteElement.type; + var interfaceType = interfaceMembers.map[name]; + + // The case when members have different kinds is reported in verifier. + if (concreteType.element.kind != interfaceType.element.kind) { + continue; + } + + // If a class declaration is not abstract, and the interface has a + // member declaration named `m`, then: + // 1. if the class contains a non-overridden member whose signature is + // not a valid override of the interface member signature for `m`, + // then it's a compile-time error. + // 2. if the class contains no member named `m`, and the class member + // for `noSuchMethod` is the one declared in `Object`, then it's a + // compile-time error. TODO(scheglov) implement this + if (!_typeSystem.isOverrideSubtypeOf(concreteType, interfaceType)) { + _reporter.reportErrorForNode( + CompileTimeErrorCode.INVALID_OVERRIDE, + classNameNode, + [ + name, + concreteElement.enclosingElement.name, + concreteType.displayName, + interfaceType.element.enclosingElement.name, + interfaceType.displayName + ], + ); + } + } + } + } +} + +/// Description of a failure to find a valid override from superinterfaces. +class _Conflict { + /// The name of an instance member for which we failed to find a valid + /// override. + final String name; + + /// The list of candidates for a valid override for a member [name]. It has + /// at least two items, because otherwise the only candidate is always valid. + final List candidates; + + final FunctionType getter; + final FunctionType method; + + _Conflict(this.name, this.candidates, [this.getter, this.method]); +} + +/// The instance interface of an [InterfaceType]. +class _Interface { + final Map map; + final List<_Conflict> conflicts; + + _Interface(this.map, this.conflicts); +} diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart index eb12686512022..3c84e61fa3e52 100644 --- a/pkg/analyzer/lib/src/fasta/error_converter.dart +++ b/pkg/analyzer/lib/src/fasta/error_converter.dart @@ -364,7 +364,7 @@ class FastaErrorReporter { return; case "INVALID_METHOD_OVERRIDE": errorReporter?.reportErrorForOffset( - StrongModeCode.INVALID_METHOD_OVERRIDE, offset, length); + CompileTimeErrorCode.INVALID_OVERRIDE, offset, length); return; case "INVALID_MODIFIER_ON_SETTER": _reportByCode(CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER, message, diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart index cf3cc20807a91..4655343b08f44 100644 --- a/pkg/analyzer/lib/src/generated/error_verifier.dart +++ b/pkg/analyzer/lib/src/generated/error_verifier.dart @@ -4283,7 +4283,7 @@ class ErrorVerifier extends RecursiveAstVisitor { var superMember = enclosingType.lookUpInheritedMember( name, _currentLibrary, concrete: true, - stopMixinIndex: mixinIndex, + startMixinIndex: mixinIndex, setter: name.endsWith('=')); if (superMember == null) { _errorReporter.reportErrorForNode( diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart index 96e26324242b4..616c16a13abdb 100644 --- a/pkg/analyzer/lib/src/task/dart.dart +++ b/pkg/analyzer/lib/src/task/dart.dart @@ -26,6 +26,7 @@ import 'package:analyzer/src/dart/scanner/scanner.dart'; import 'package:analyzer/src/dart/sdk/patch.dart'; import 'package:analyzer/src/dart/sdk/sdk.dart'; import 'package:analyzer/src/error/codes.dart'; +import 'package:analyzer/src/error/inheritance_override.dart'; import 'package:analyzer/src/error/pending_error.dart'; import 'package:analyzer/src/generated/constant.dart'; import 'package:analyzer/src/generated/declaration_resolver.dart'; @@ -5553,6 +5554,14 @@ class VerifyUnitTask extends SourceBasedAnalysisTask { ConstantVerifier constantVerifier = new ConstantVerifier( errorReporter, libraryElement, typeProvider, context.declaredVariables); unit.accept(constantVerifier); + + // + // Compute inheritance and override errors. + // + var inheritanceOverrideVerifier = new InheritanceOverrideVerifier( + libraryElement.context.typeSystem, errorReporter); + inheritanceOverrideVerifier.verifyUnit(unit); + // // Use the ErrorVerifier to compute errors. // diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart index 74f65da65d93a..efe990e8f0dd9 100644 --- a/pkg/analyzer/lib/src/task/strong/checker.dart +++ b/pkg/analyzer/lib/src/task/strong/checker.dart @@ -95,33 +95,6 @@ Element _getKnownElement(Expression expression) { return null; } -/// Return the field on type corresponding to member, or null if none -/// exists or the "field" is actually a getter/setter. -FieldElement _getMemberField( - InterfaceType type, PropertyAccessorElement member) { - String memberName = member.name; - FieldElement field; - if (member.isGetter) { - // The subclass member is an explicit getter or a field - // - lookup the getter on the superclass. - var getter = type.getGetter(memberName); - if (getter == null || getter.isStatic) return null; - field = getter.variable; - } else if (!member.isSynthetic) { - // The subclass member is an explicit setter - // - lookup the setter on the superclass. - // Note: an implicit (synthetic) setter would have already been flagged on - // the getter above. - var setter = type.getSetter(memberName); - if (setter == null || setter.isStatic) return null; - field = setter.variable; - } else { - return null; - } - if (field.isSynthetic) return null; - return field; -} - /// Looks up the declaration that matches [member] in [type] and returns it's /// declared type. FunctionType _getMemberType(InterfaceType type, ExecutableElement member) { @@ -1276,11 +1249,8 @@ class CodeChecker extends RecursiveAstVisitor { /// applications. class _OverrideChecker { final StrongTypeSystemImpl rules; - final CodeChecker _checker; - _OverrideChecker(CodeChecker checker) - : _checker = checker, - rules = checker.rules; + _OverrideChecker(CodeChecker checker) : rules = checker.rules; void check(Declaration node) { var element = @@ -1288,9 +1258,6 @@ class _OverrideChecker { if (element.type.isObject) { return; } - _checkSuperOverrides(node, element); - _checkMixinApplicationOverrides(node, element); - _checkAllInterfaceOverrides(node, element); _checkForCovariantGenerics(node, element); } @@ -1568,133 +1535,6 @@ class _OverrideChecker { return genericSupertypes; } - /// Checks that most-derived concrete members on this class correctly override - /// all reachable interfaces, and reports errors if all interfaces are not - /// correctly implemented. - /// - /// This checks the soundness property: for all interfaces implemented by this - /// class (including inherited interfaces), we ensure that calls through that - /// interface will be sound. - void _checkAllInterfaceOverrides(Declaration node, ClassElement element) { - var interfaces = _collectInterfacesToCheck(element.type); - var visitedClasses = new Set(); - var visitedMembers = new HashSet(); - - // Checks all most-derived concrete members on this `type`. We skip over - // members that are already `visitedMembers`, because they were overridden - // and we've already checked that member. - // - // Because of that, it is important we visit types in the order that they - // will override members. - // If checkingMixin is true, then we are checking [type] in a mixin position - // and hence should consider its own mixins and superclass as abstract. - void checkType(InterfaceType type, AstNode location, - {bool checkingMixin: false}) { - // Skip `Object` because we don't need to check those members here. - // (because `Object` is the root of everything, it will be checked in - // _checkSuperOverrides for all classes). - if (type == null || type.isObject || !visitedClasses.add(type)) return; - - // Check `member` against all `interfaces`. - void checkOverride(ExecutableElement member, [AstNode loc]) { - if (!visitedMembers.add(member.name)) return; - for (var interface in interfaces) { - if (_checkMemberOverride(member, interface, loc ?? location) == - false) { - // Only report one error per member for interfaces. - // TODO(jmesserly): this is for backwards compatibility. Remove it? - break; - } - } - } - - // When we're checking the class declaration node we started from, we - // can use a more precise error location for reporting override errors. - // - // Otherwise, we'll use the `extends` or `with` clause. - var isRootClass = identical(location, node); - - // Check direct overrides on the class. - if (isRootClass) { - _checkClassMembers(node, checkOverride); - } else { - _checkTypeMembers(type, checkOverride); - } - - // If we are currently checking a mixin, then its own mixins and - // superclass are abstract, and we should not check their members. - // This should only happen when super mixins is enabled, and we - // don't do proper checking for super mixins (we don't check that - // the contract implied by the mixin declaration is satisfied by - // the mixin use), but this prevents us from erroneously - // rejecting some super mixin patterns. - // If this is a mixin application (class A = Object with B) - // however, then we do still need to treat the mixin as concrete. - if (!checkingMixin || type.element.isMixinApplication) { - // Check mixin members against interfaces. - // - // We visit mixins in reverse order to reflect how they override - // eachother. - for (int i = type.mixins.length - 1; i >= 0; i--) { - checkType(type.mixins[i], - isRootClass ? _withClause(node).mixinTypes[i] : location, - checkingMixin: true); - } - - // Check members on the superclass. - checkType(type.superclass, - isRootClass ? _extendsErrorLocation(node) : location, - checkingMixin: checkingMixin); - } - } - - checkType(element.type, node); - } - - /// Gets the set of all interfaces on [type] that should be checked to see - /// if type's members are overriding them correctly. - /// - /// In particular, we need to check these overrides for the definitions in - /// the class itself and each its superclasses (and mixins). - /// If a superclass (or mixin) is concrete, then we can skip its transitive - /// interfaces, but if it is abstract we must check them. For example, in: - /// - /// B extends C implements G - /// A extends B with E, F implements H, I - /// - /// we need to check the following interfaces: - /// - /// C against G, H, and I - /// B against G, H, and I - /// E against H and I // no check against G because B is a concrete class - /// F against H and I - /// A against H and I - Set _collectInterfacesToCheck(InterfaceType type) { - var interfaces = new Set(); - void collectInterfaces(InterfaceType t) { - if (t == null || t.isObject) return; - if (!interfaces.add(t)) return; - collectInterfaces(t.superclass); - t.mixins.forEach(collectInterfaces); - t.interfaces.forEach(collectInterfaces); - } - - // Check all interfaces reachable from the `implements` clause in the - // current class against definitions here and in superclasses. - type.interfaces.forEach(collectInterfaces); - - // Also collect interfaces from any abstract mixins or superclasses. - // - // For a concrete mixin/superclass, we'll check that we override the - // concrete members in _checkSuperOverrides and - // _checkMixinApplicationOverrides. But for abstract classes, we need to - // consider any abstract members it got from its interfaces. - for (var s in _getSuperclasses(type, (t) => t.element.isAbstract)) { - s.interfaces.forEach(collectInterfaces); - } - return interfaces; - } - /// Visits each member on the class [node] and calls [checkMember] with the /// corresponding instance element and AST node (for error reporting). /// @@ -1739,196 +1579,11 @@ class _OverrideChecker { type.accessors.forEach(checkHelper); } - /// Check overrides from mixin applications themselves. For example, in: - /// - /// A extends B with E, F - /// - /// we check: - /// - /// B & E against B (equivalently how E overrides B) - /// B & E & F against B & E (equivalently how F overrides both B and E) - void _checkMixinApplicationOverrides(Declaration node, ClassElement element) { - var superclass = element.type.superclass; - var mixins = element.type.mixins; - - // Check overrides from applying mixins - for (int i = 0; i < mixins.length; i++) { - var current = mixins[i]; - var location = _withClause(node).mixinTypes[i]; - var superclasses = mixins.sublist(0, i).reversed.toList() - ..add(superclass); - - _checkTypeMembers(current, (m) { - for (var s in superclasses) { - if (_checkConcreteMemberOverride(m, s, location)) break; - } - }); - } - } - - /// Gets the member corresponding to [member] on [type], and returns `null` - /// if no member was found, or a boolean value to indicate whether the - /// override is valid. - /// - /// The [location] is a node where the error is reported. For example, a - /// bad override of a method in a class with respect to its superclass is - /// reported directly at the method declaration. However, invalid overrides - /// from base classes to interfaces, mixins to the base they are applied to, - /// or mixins to interfaces are reported at the class declaration, since the - /// base class or members on their own were not incorrect, only combining them - /// with the interface was problematic. For example, these are example error - /// locations in these cases: - /// - /// error: base class introduces an invalid override. The type of B.foo is - /// not a subtype of E.foo: - /// class A extends B implements E { ... } - /// ^^^^^^^^^ - /// - /// error: mixin introduces an invalid override. The type of C.foo is not - /// a subtype of E.foo: - /// class A extends B with C implements E { ... } - /// ^ - /// - /// When checking for overrides from a type and it's super types, [node] is - /// the AST node that defines [member]. This is used to determine whether the - /// type of the element could be inferred from the types in the super classes. - bool _checkMemberOverride( - ExecutableElement member, InterfaceType type, AstNode location) { - assert(!member.isStatic); - - FunctionType subType = _elementType(member); - FunctionType baseType = _getMemberType(type, member); - if (baseType == null) return null; - - if (!rules.isOverrideSubtypeOf(subType, baseType)) { - ErrorCode errorCode; - var parent = location?.parent; - if (location is ExtendsClause || - parent is ClassTypeAlias && parent.superclass == location) { - errorCode = StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_BASE; - } else if (parent is WithClause) { - errorCode = StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_MIXIN; - } else { - errorCode = StrongModeCode.INVALID_METHOD_OVERRIDE; - } - - _checker._recordMessage(location, errorCode, - [member.enclosingElement.name, member.name, subType, type, baseType]); - return false; - } - return true; - } - - /// Checks that a member override from a superclass (i.e. a concrete member) - /// is correct, reporting an error if needed, and returns `true` if we should - /// keep searching up the superclass chain. - bool _checkConcreteMemberOverride( - ExecutableElement member, InterfaceType type, AstNode location) { - _checkFieldOverride(member, type, location); - // Stop if a member was found, and we have no covariant parameters. - // If we have covariant parameters, we need to keep searching. - return _checkMemberOverride(member, type, location) != null && - member.parameters.every((p) => !p.isCovariant); - } - - void _checkFieldOverride( - Element member, InterfaceType type, AstNode location) { - if (member is PropertyAccessorElement) { - // Disallow overriding a non-virtual field. - var field = _getMemberField(type, member); - if (field != null && !field.isVirtual) { - FunctionType subType = _elementType(member); - FunctionType baseType = _getMemberType(type, member); - _checker._recordMessage( - location, StrongModeCode.INVALID_FIELD_OVERRIDE, [ - member.enclosingElement.name, - member.name, - subType, - type, - baseType - ]); - } - } - } - - /// Check overrides between a class and its superclasses and mixins. For - /// example, in: - /// - /// A extends B with E, F - /// - /// we check A against B, B super classes, E, and F. - /// - /// Internally we avoid reporting errors twice and we visit classes bottom up - /// to ensure we report the most immediate invalid override first. For - /// example, in the following code we'll report that `Test` has an invalid - /// override with respect to `Parent` (as opposed to an invalid override with - /// respect to `Grandparent`): - /// - /// class Grandparent { - /// m(A a) {} - /// } - /// class Parent extends Grandparent { - /// m(A a) {} - /// } - /// class Test extends Parent { - /// m(B a) {} // invalid override - /// } - void _checkSuperOverrides(Declaration node, ClassElement element) { - var superclasses = _getSuperclasses(element.type); - _checkClassMembers(node, (member, loc) { - for (var s in superclasses) { - if (_checkConcreteMemberOverride(member, s, loc)) break; - } - }); - } - - /// Collects all superclasses of [type], including any mixin application - /// classes. - /// - /// The search can be pruned by passing a [visitSuperclasses] function and - /// having it return `false` for types that should not be further explored. - Iterable _getSuperclasses(InterfaceType type, - [bool visitSuperclasses(InterfaceType t)]) { - var superclasses = new Set(); - visit(InterfaceType t) { - if ((visitSuperclasses == null || visitSuperclasses(t)) && - superclasses.add(t)) { - t.mixins.reversed.forEach(visit); - var s = t.superclass; - if (s != null && !s.isObject) visit(s); - } - } - - type.mixins.reversed.forEach(visit); - var s = type.superclass; - if (s != null && !s.isObject) visit(s); - - // Make sure we record Object last, and not when we visit our mixins. - if (!type.isObject) visit(rules.typeProvider.objectType); - return superclasses; - } - /// If node is a [ClassDeclaration] returns its members, otherwise if node is /// a [ClassTypeAlias] this returns an empty list. Iterable _classMembers(Declaration node) { return node is ClassDeclaration ? node.members : []; } - - /// If node is a [ClassDeclaration] returns its members, otherwise if node is - /// a [ClassTypeAlias] this returns an empty list. - AstNode _extendsErrorLocation(Declaration node) { - return node is ClassDeclaration - ? node.extendsClause - : (node as ClassTypeAlias).superclass; - } - - /// If node is a [ClassDeclaration] returns its members, otherwise if node is - /// a [ClassTypeAlias] this returns an empty list. - WithClause _withClause(Declaration node) { - return node is ClassDeclaration - ? node.withClause - : (node as ClassTypeAlias).withClause; - } } class _TopLevelInitializerValidator extends RecursiveAstVisitor { diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart index 724f3b8c46f7f..dbfb8a2ace96c 100644 --- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart +++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart @@ -2649,10 +2649,20 @@ class C = B with M implements a.A;''' test_implementsDisallowedClass_class_String_num() async { Source source = addSource("class A implements String, num {}"); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, - CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS - ]); + if (enableNewAnalysisDriver) { + assertErrors(source, [ + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS + ]); + } else { + assertErrors(source, [ + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS + ]); + } verify([source]); } @@ -2722,10 +2732,20 @@ class A {} class M {} class C = A with M implements String, num;'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, - CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS - ]); + if (enableNewAnalysisDriver) { + assertErrors(source, [ + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS + ]); + } else { + assertErrors(source, [ + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS + ]); + } verify([source]); } @@ -4231,14 +4251,18 @@ class C = A with String;'''); class A {} class C = A with String, num;'''); await computeAnalysisResult(source); - if (previewDart2) { + if (enableNewAnalysisDriver) { assertErrors(source, [ - StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_MIXIN, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.INVALID_OVERRIDE, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS ]); } else { assertErrors(source, [ + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + CompileTimeErrorCode.INVALID_OVERRIDE, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS ]); diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart index a6873453b2a1f..208b63789fd04 100644 --- a/pkg/analyzer/test/generated/non_hint_code_test.dart +++ b/pkg/analyzer/test/generated/non_hint_code_test.dart @@ -658,7 +658,10 @@ class B implements A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors( + source, + [CompileTimeErrorCode.INVALID_OVERRIDE], + ); } else { assertNoErrors(source); } @@ -682,7 +685,10 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors( + source, + [CompileTimeErrorCode.INVALID_OVERRIDE], + ); } else { assertNoErrors(source); } diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart index 5003da0e499d1..825e0fb031fd6 100644 --- a/pkg/analyzer/test/generated/static_warning_code_test.dart +++ b/pkg/analyzer/test/generated/static_warning_code_test.dart @@ -1859,12 +1859,7 @@ class B extends A { String get g { return 'a'; } }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -1877,17 +1872,10 @@ class B extends A { int f; }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [ - StrongModeCode.INVALID_METHOD_OVERRIDE, - StrongModeCode.INVALID_METHOD_OVERRIDE - ]); - } else { - assertErrors(source, [ - StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, - StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE - ]); - } + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); verify([source]); } @@ -1905,12 +1893,10 @@ class B extends A { String get getter => null; }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE, + ]); verify([source]); } @@ -1926,12 +1912,10 @@ class B implements I, J { double get g => null; }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); verify([source]); } @@ -1944,12 +1928,7 @@ class B implements A { m({String a}) {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -1962,12 +1941,7 @@ class B implements A { m(String a) {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors(source, - [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -1980,12 +1954,7 @@ class B extends A { m(String a) {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors(source, - [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -2001,15 +1970,10 @@ class B extends I implements J { m(double d) {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [ - StrongModeCode.INVALID_METHOD_OVERRIDE, - StrongModeCode.INVALID_METHOD_OVERRIDE - ]); - } else { - assertErrors(source, - [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); - } + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); verify([source]); } @@ -2026,12 +1990,10 @@ class B extends A { m(String n) {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors(source, - [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); - } + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); verify([source]); } @@ -2048,12 +2010,10 @@ class B implements I, J { m(double d) {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors(source, - [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); - } + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); verify([source]); } @@ -2066,12 +2026,7 @@ class B implements A { m([String a]) {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors(source, - [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -2088,12 +2043,10 @@ class B extends A { m([String n]) {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors(source, - [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]); - } + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); verify([source]); } @@ -2106,12 +2059,7 @@ class B implements A { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -2126,12 +2074,7 @@ class C implements B { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -2144,12 +2087,7 @@ class B extends Object with A { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -2162,12 +2100,7 @@ class B extends A { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -2182,12 +2115,7 @@ class C extends B { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -2204,12 +2132,10 @@ class B extends A { String m() => ''; }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); verify([source]); } @@ -2222,12 +2148,7 @@ class B extends A { void m() {} }'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); - } else { - assertErrors( - source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -2393,7 +2314,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_NAMED]); } @@ -2410,7 +2331,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_NAMED]); } @@ -2427,7 +2348,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]); } @@ -2444,7 +2365,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]); } @@ -2461,7 +2382,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]); } @@ -2478,7 +2399,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_REQUIRED]); } @@ -2495,7 +2416,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]); @@ -2518,9 +2439,8 @@ class B extends A { await computeAnalysisResult(source); if (previewDart2) { assertErrors(source, [ - StrongModeCode.INVALID_METHOD_OVERRIDE, - StrongModeCode.INVALID_METHOD_OVERRIDE, - StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_BASE + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE, ]); } else { assertErrors(source, @@ -2544,7 +2464,10 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); } else { assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]); @@ -2565,7 +2488,10 @@ class B implements I, J { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [ + CompileTimeErrorCode.INVALID_OVERRIDE, + CompileTimeErrorCode.INVALID_OVERRIDE + ]); } else { assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]); @@ -2923,12 +2849,7 @@ abstract class D { } class E extends C implements D {}'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_BASE]); - } else { - assertErrors(source, - [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]); - } + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart index 0456a6fbbae58..d302e2f9b8305 100644 --- a/pkg/analyzer/test/generated/strong_mode_test.dart +++ b/pkg/analyzer/test/generated/strong_mode_test.dart @@ -3460,7 +3460,7 @@ class D extends C { T f(T x) => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -3475,7 +3475,7 @@ class D extends C { T f(T x) => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -3488,7 +3488,7 @@ class D extends C { String f(S x) => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } @@ -3501,7 +3501,7 @@ class D extends C { S f(T x) => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); verify([source]); } diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart index 02afc122a99aa..c98f7139747f1 100644 --- a/pkg/analyzer/test/src/dart/resolution/class_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart @@ -1291,7 +1291,7 @@ class C { expect(method.isStatic, isTrue); } - test_inconsistentMethodInheritance_parameterType() async { + test_inconsistentInheritance_parameterType() async { addTestFile(r''' abstract class A { x(int i); @@ -1303,11 +1303,11 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } - test_inconsistentMethodInheritance_requiredParameters() async { + test_inconsistentInheritance_requiredParameters() async { addTestFile(r''' abstract class A { x(); @@ -1319,11 +1319,11 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } - test_inconsistentMethodInheritance_returnType() async { + test_inconsistentInheritance_returnType() async { addTestFile(r''' abstract class A { int x(); @@ -1335,11 +1335,11 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } - test_inconsistentMethodInheritanceGetterAndMethod_getter_method() async { + test_inconsistentInheritanceGetterAndMethod_getter_method() async { addTestFile(r''' abstract class A { int get x; @@ -1351,11 +1351,11 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentMethodInheritanceGetterAndMethod_method_getter() async { + test_inconsistentInheritanceGetterAndMethod_method_getter() async { addTestFile(r''' abstract class A { int x(); @@ -1367,7 +1367,7 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, ]); } diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart index 52d0187a945dc..90dbab84e7d3e 100644 --- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart @@ -1423,163 +1423,163 @@ mixin M implements A, B {} // M assertTypeName(bRef, findElement.class_('B'), 'B'); } - test_inconsistentMethodInheritance_implements_parameterType() async { + test_inconsistentInheritanceGetterAndMethod_implements_getter_method() async { addTestFile(r''' abstract class A { - x(int i); + int get x; } abstract class B { - x(String s); + int x(); } mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentMethodInheritance_implements_requiredParameters() async { + test_inconsistentInheritanceGetterAndMethod_implements_method_getter() async { addTestFile(r''' abstract class A { - x(); + int x(); } abstract class B { - x(int y); + int get x; } mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentMethodInheritance_implements_returnType() async { + test_inconsistentInheritanceGetterAndMethod_on_getter_method() async { addTestFile(r''' abstract class A { - int x(); + int get x; } abstract class B { - String x(); + int x(); } mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentMethodInheritance_on_parameterType() async { + test_inconsistentInheritanceGetterAndMethod_on_method_getter() async { addTestFile(r''' abstract class A { - x(int i); + int x(); } abstract class B { - x(String s); + int get x; } -mixin M on A, B {} +mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentMethodInheritance_on_requiredParameters() async { + test_inconsistentInheritance_implements_parameterType() async { addTestFile(r''' abstract class A { - x(); + x(int i); } abstract class B { - x(int y); + x(String s); } -mixin M on A, B {} +mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } - test_inconsistentMethodInheritance_on_returnType() async { + test_inconsistentInheritance_implements_requiredParameters() async { addTestFile(r''' abstract class A { - int x(); + x(); } abstract class B { - String x(); + x(int y); } -mixin M on A, B {} +mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } - test_inconsistentMethodInheritanceGetterAndMethod_implements_getter_method() async { + test_inconsistentInheritance_implements_returnType() async { addTestFile(r''' abstract class A { - int get x; + int x(); } abstract class B { - int x(); + String x(); } mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } - test_inconsistentMethodInheritanceGetterAndMethod_implements_method_getter() async { + test_inconsistentInheritance_on_parameterType() async { addTestFile(r''' abstract class A { - int x(); + x(int i); } abstract class B { - int get x; + x(String s); } -mixin M implements A, B {} +mixin M on A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } - test_inconsistentMethodInheritanceGetterAndMethod_on_getter_method() async { + test_inconsistentInheritance_on_requiredParameters() async { addTestFile(r''' abstract class A { - int get x; + x(); } abstract class B { - int x(); + x(int y); } -mixin M implements A, B {} +mixin M on A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } - test_inconsistentMethodInheritanceGetterAndMethod_on_method_getter() async { + test_inconsistentInheritance_on_returnType() async { addTestFile(r''' abstract class A { int x(); } abstract class B { - int get x; + String x(); } -mixin M implements A, B {} +mixin M on A, B {} '''); await resolveTestFile(); assertTestErrors([ - StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, + CompileTimeErrorCode.INCONSISTENT_INHERITANCE, ]); } diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart index 939596cf9ec01..65921c71ce90b 100644 --- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart +++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart @@ -332,7 +332,7 @@ abstract class B { String aaa; } class C implements A, B { - /*error:INVALID_METHOD_OVERRIDE*/var aaa; + /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/var aaa; } '''; await checkFile(content); diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart index e2a86820eed20..e00db4fca6499 100644 --- a/pkg/analyzer/test/src/task/options_test.dart +++ b/pkg/analyzer/test/src/task/options_test.dart @@ -227,9 +227,6 @@ class ErrorCodeValuesTest { removeCode(StrongModeCode.INVALID_SUPER_INVOCATION); removeCode(StrongModeCode.NON_GROUND_TYPE_CHECK_INFO); removeCode(StrongModeCode.DYNAMIC_INVOKE); - removeCode(StrongModeCode.INVALID_METHOD_OVERRIDE); - removeCode(StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_BASE); - removeCode(StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_MIXIN); removeCode(StrongModeCode.INVALID_FIELD_OVERRIDE); removeCode(StrongModeCode.IMPLICIT_DYNAMIC_PARAMETER); removeCode(StrongModeCode.IMPLICIT_DYNAMIC_RETURN); diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart index 994a8bd572c31..c2b055c6a2734 100644 --- a/pkg/analyzer/test/src/task/strong/checker_test.dart +++ b/pkg/analyzer/test/src/task/strong/checker_test.dart @@ -172,7 +172,7 @@ abstract class I1 { abstract class Base implements I1 {} class T1 extends Base { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -190,10 +190,7 @@ class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base implements I1 {} class T1 extends Base { - // not reported technically because if the class is concrete, - // it should implement all its interfaces and hence it is - // sufficient to check overrides against it. - m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -209,7 +206,7 @@ abstract class I1 { abstract class I2 implements I1 {} class T1 implements I2 { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -225,7 +222,7 @@ abstract class M1 { abstract class I2 extends Object with M1 {} class T1 implements I2 { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -241,7 +238,7 @@ abstract class I1 { abstract class I2 extends I1 {} class T1 implements I2 { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -546,20 +543,21 @@ class F extends E { class G extends E implements D {} class D_error extends C { - /*error:INVALID_METHOD_OVERRIDE*/int f(int x) => x; + /*error:INVALID_OVERRIDE*/int f(int x) => x; } class E_error extends D { - /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0; + /*error:INVALID_OVERRIDE*/int f(@checked double x) => 0; } class F_error extends E { - /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0; + /*error:INVALID_OVERRIDE*/int f(@checked double x) => 0; } class G_error extends E implements D { - /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0; + /*error:INVALID_OVERRIDE*/int f(@checked double x) => 0; } '''); } + @failingTest test_covariantOverride_fields() async { _addMetaLibrary(); await checkFile(r''' @@ -579,7 +577,7 @@ class D extends C { @virtual int foo; } class E extends D { - @virtual /*error:INVALID_METHOD_OVERRIDE*/num foo; + @virtual num foo; } '''); } @@ -628,16 +626,16 @@ class F extends E { class G extends E implements D {} class D_error extends C { - /*error:INVALID_METHOD_OVERRIDE*/int f(String x) => 0; + /*error:INVALID_OVERRIDE*/int f(String x) => 0; } class E_error extends D { - /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0; + /*error:INVALID_OVERRIDE*/int f(double x) => 0; } class F_error extends E { - /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0; + /*error:INVALID_OVERRIDE*/int f(double x) => 0; } class G_error extends E implements D { - /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0; + /*error:INVALID_OVERRIDE*/int f(double x) => 0; } '''); } @@ -730,17 +728,17 @@ class Base { } class Child extends Base { - /*error:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter - /*error:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter + /*error:INVALID_OVERRIDE*/A f1; // invalid for getter + /*error:INVALID_OVERRIDE*/C f2; // invalid for setter var f3; - /*error:INVALID_METHOD_OVERRIDE*/dynamic f4; + /*error:INVALID_OVERRIDE*/dynamic f4; } class Child2 implements Base { - /*error:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter - /*error:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter + /*error:INVALID_OVERRIDE*/A f1; // invalid for getter + /*error:INVALID_OVERRIDE*/C f2; // invalid for setter var f3; - /*error:INVALID_METHOD_OVERRIDE*/dynamic f4; + /*error:INVALID_OVERRIDE*/dynamic f4; } '''); } @@ -759,17 +757,17 @@ abstract class Base { } class Child extends Base { - /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null; + /*error:INVALID_OVERRIDE*/A get f1 => null; C get f2 => null; get f3 => null; - /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null; + /*error:INVALID_OVERRIDE*/dynamic get f4 => null; } class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implements Base { - /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null; + /*error:INVALID_OVERRIDE*/A get f1 => null; C get f2 => null; get f3 => null; - /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null; + /*error:INVALID_OVERRIDE*/dynamic get f4 => null; } '''); } @@ -783,12 +781,12 @@ class F { } class G extends F { - /*error:INVALID_METHOD_OVERRIDE*/final ToVoid f = null; + /*error:INVALID_OVERRIDE*/final ToVoid f = null; final ToVoid g = null; } class H implements F { - /*error:INVALID_METHOD_OVERRIDE*/final ToVoid f = null; + /*error:INVALID_OVERRIDE*/final ToVoid f = null; final ToVoid g = null; } '''); @@ -846,7 +844,7 @@ class Child extends Base { B get f5 => null; void set f1(A value) {} - /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {} + /*error:INVALID_OVERRIDE*/void set f2(C value) {} void set f3(value) {} void set f4(dynamic value) {} set f5(B value) {} @@ -860,7 +858,7 @@ class Child2 implements Base { B get f5 => null; void set f1(A value) {} - /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {} + /*error:INVALID_OVERRIDE*/void set f2(C value) {} void set f3(value) {} void set f4(dynamic value) {} set f5(B value) {} @@ -1966,7 +1964,7 @@ class Base { } class Derived extends Base { - /*error:INVALID_METHOD_OVERRIDE*/S foo() => null; + /*error:INVALID_OVERRIDE*/S foo() => null; } class Derived2 extends Base { @@ -2074,10 +2072,10 @@ abstract class Base { } class Child extends Base { - /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null; + /*error:INVALID_OVERRIDE*/A get f1 => null; C get f2 => null; get f3 => null; - /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null; + /*error:INVALID_OVERRIDE*/dynamic get f4 => null; } '''); } @@ -2092,12 +2090,12 @@ class F { } class G extends F { - /*error:INVALID_METHOD_OVERRIDE*/ToVoid get f => null; + /*error:INVALID_OVERRIDE*/ToVoid get f => null; ToVoid get g => null; } class H implements F { - /*error:INVALID_METHOD_OVERRIDE*/ToVoid get f => null; + /*error:INVALID_OVERRIDE*/ToVoid get f => null; ToVoid get g => null; } '''); @@ -2552,7 +2550,7 @@ class C { set x(Object y) {} } class D implements B, C { - /*error:INVALID_METHOD_OVERRIDE*/int x; + /*error:INVALID_OVERRIDE*/int x; } '''); } @@ -2566,13 +2564,13 @@ abstract class I { abstract class M implements I {} class C extends Object with M { - /*error:INVALID_METHOD_OVERRIDE*/String x; + /*error:INVALID_OVERRIDE*/String x; } abstract class M2 = Object with M; class C2 extends Object with M2 { - /*error:INVALID_METHOD_OVERRIDE*/String x; + /*error:INVALID_OVERRIDE*/String x; } '''); } @@ -2603,13 +2601,13 @@ abstract class I { abstract class M implements I {} class C extends Object with M { - /*error:INVALID_METHOD_OVERRIDE*/String x; + /*error:INVALID_OVERRIDE*/String x; } abstract class D extends Object with M {} /*error:CONFLICTING_GENERIC_INTERFACES*/ /*error:CONFLICTING_GENERIC_INTERFACES*/class E extends D with M { - /*error:INVALID_METHOD_OVERRIDE*/int x; + /*error:INVALID_OVERRIDE*/int x; } /*error:CONFLICTING_GENERIC_INTERFACES*/ /*error:CONFLICTING_GENERIC_INTERFACES*/class F extends D with M { @@ -2631,8 +2629,8 @@ class Base { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I {} +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Base implements I {} '''); } @@ -2646,37 +2644,37 @@ class Base { } class T1 extends Base { - /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,error:INVALID_METHOD_OVERRIDE*/B get f => null; + /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,error:INVALID_OVERRIDE*/B get f => null; } class T2 extends Base { - /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,error:INVALID_METHOD_OVERRIDE*/set f( + /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,error:INVALID_OVERRIDE*/set f( B b) => null; } class T3 extends Base { - /*error:INVALID_METHOD_OVERRIDE*/final B + /*error:INVALID_OVERRIDE*/final B /*error:FINAL_NOT_INITIALIZED*/f; } class T4 extends Base { // two: one for the getter one for the setter. - /*error:INVALID_METHOD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/B f; + /*error:INVALID_OVERRIDE, error:INVALID_OVERRIDE*/B f; } class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T5 implements Base { - /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_METHOD_OVERRIDE*/B get f => null; + /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_OVERRIDE*/B get f => null; } class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T6 implements Base { - /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_METHOD_OVERRIDE*/set f(B b) => null; + /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_OVERRIDE*/set f(B b) => null; } class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Base { - /*error:INVALID_METHOD_OVERRIDE*/final B f = null; + /*error:INVALID_OVERRIDE*/final B f = null; } class T8 implements Base { // two: one for the getter one for the setter. - /*error:INVALID_METHOD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/B f; + /*error:INVALID_OVERRIDE, error:INVALID_OVERRIDE*/B f; } '''); } @@ -2691,7 +2689,7 @@ class Base { } class Test extends Base { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -2706,11 +2704,12 @@ abstract class I { } class T1 implements I { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } + @failingTest test_invalidOverrides_doubleOverride() async { await checkFile(''' class A {} @@ -2725,11 +2724,12 @@ class Parent extends Grandparent { class Test extends Parent { // Reported only once - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } + @failingTest test_invalidOverrides_doubleOverride2() async { await checkFile(''' class A {} @@ -2739,7 +2739,7 @@ class Grandparent { m(A a) {} } class Parent extends Grandparent { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } class Test extends Parent { @@ -2761,7 +2761,7 @@ class Parent extends Grandparent { } class Test extends Parent { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} int x; } '''); @@ -2780,12 +2780,12 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Object with M implements I {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Object - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I; +class /*error:INCONSISTENT_INHERITANCE*/U1 = Object + with M implements I; '''); } @@ -2807,20 +2807,20 @@ class M2 { int x; } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2 extends Base - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1, M2 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T3 extends Base - with M2, /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1 {} +class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base + with /*error:INVALID_OVERRIDE*/M1 {} +class /*error:INCONSISTENT_INHERITANCE*/T2 extends Base + with /*error:INVALID_OVERRIDE*/M1, M2 {} +class /*error:INCONSISTENT_INHERITANCE*/T3 extends Base + with M2, /*error:INVALID_OVERRIDE*/M1 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1; -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U2 = Base - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1, M2; -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U3 = Base - with M2, /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1; +class /*error:INCONSISTENT_INHERITANCE*/U1 = Base + with /*error:INVALID_OVERRIDE*/M1; +class /*error:INCONSISTENT_INHERITANCE*/U2 = Base + with /*error:INVALID_OVERRIDE*/M1, M2; +class /*error:INCONSISTENT_INHERITANCE*/U3 = Base + with M2, /*error:INVALID_OVERRIDE*/M1; '''); } @@ -2842,16 +2842,17 @@ class M2 { int x; } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base +class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base with M1, - /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2 {} + /*error:INVALID_OVERRIDE*/M2 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base +class /*error:INCONSISTENT_INHERITANCE*/U1 = Base with M1, - /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2; + /*error:INVALID_OVERRIDE*/M2; '''); } + @failingTest test_invalidOverrides_noDuplicateMixinOverride() async { // This is a regression test for a bug in an earlier implementation were // names were hiding errors if the first mixin override looked correct, @@ -2876,11 +2877,11 @@ class M3 { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base - with M1, /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2, M3 {} +class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base + with M1, /*error:INVALID_OVERRIDE_FROM_MIXIN*/M2, M3 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base - with M1, /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2, M3; +class /*error:INCONSISTENT_INHERITANCE*/U1 = Base + with M1, /*error:INVALID_OVERRIDE_FROM_MIXIN*/M2, M3; '''); } @@ -2899,20 +2900,20 @@ class I1 { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Base implements I1 {} class T2 extends Base implements I1 { m(a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T3 - extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/Base +class /*error:INCONSISTENT_INHERITANCE*/T3 + extends Object with Base implements I1 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U3 - = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/Base +class /*error:INCONSISTENT_INHERITANCE*/U3 + = Object with Base implements I1; class T4 extends Object with Base implements I1 { @@ -3050,12 +3051,12 @@ class Base { } class Child extends Base { - /*error:INVALID_METHOD_OVERRIDE*/A m1(A value) => null; - /*error:INVALID_METHOD_OVERRIDE*/C m2(C value) => null; - /*error:INVALID_METHOD_OVERRIDE*/A m3(C value) => null; + /*error:INVALID_OVERRIDE*/A m1(A value) => null; + /*error:INVALID_OVERRIDE*/C m2(C value) => null; + /*error:INVALID_OVERRIDE*/A m3(C value) => null; C m4(A value) => null; m5(value) => null; - /*error:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) => null; + /*error:INVALID_OVERRIDE*/dynamic m6(dynamic value) => null; } '''); } @@ -3074,12 +3075,12 @@ class F { } class G extends F { - /*error:INVALID_METHOD_OVERRIDE*/void f(int x) {} + /*error:INVALID_OVERRIDE*/void f(int x) {} void g(dynamic x) {} } class H implements F { - /*error:INVALID_METHOD_OVERRIDE*/void f(int x) {} + /*error:INVALID_OVERRIDE*/void f(int x) {} void g(dynamic x) {} } '''); @@ -3109,7 +3110,7 @@ class B { class C = Object with B; -class D extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/C implements A {} +class D extends Object with C implements A {} '''); } @@ -3127,11 +3128,11 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M {} +class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base + with /*error:INVALID_OVERRIDE*/M {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M; +class /*error:INCONSISTENT_INHERITANCE*/U1 = Base + with /*error:INVALID_OVERRIDE*/M; '''); } @@ -3151,9 +3152,11 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base with M {} +class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base + with /*error:INVALID_OVERRIDE*/M {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base with M; +class /*error:INCONSISTENT_INHERITANCE*/U1 = Base + with /*error:INVALID_OVERRIDE*/M; '''); } @@ -3171,12 +3174,12 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Object with M implements I2 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 - = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/U1 + = Object with M implements I2; '''); } @@ -3195,12 +3198,12 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Object with M implements I2 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 - = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/U1 + = Object with M implements I2; '''); } @@ -3219,12 +3222,12 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Object with M implements I2 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 - = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/U1 + = Object with M implements I2; '''); } @@ -3249,14 +3252,14 @@ class M { // TODO(jmesserly): the `INCONSISTENT_METHOD_INHERITANCE` message is from the // Dart 1 checking logic (using strong mode type system), it is not produced // by the strong mode OverrideChecker. -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 +class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M + with M implements I1 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = +class /*error:INCONSISTENT_INHERITANCE*/U1 = Base - with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M + with M implements I1; '''); } @@ -3280,11 +3283,11 @@ class Parent1 extends Grandparent { class Parent2 extends Grandparent {} // Note: otherwise both errors would be reported on this line -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent1 +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Parent1 implements I1 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2 - /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent2 +class /*error:INCONSISTENT_INHERITANCE*/T2 + extends Parent2 implements I1 {} '''); } @@ -3306,9 +3309,8 @@ class M2 { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Object - with M1, - /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2 +class /*error:INCONSISTENT_INHERITANCE*/T1 extends Object + with M1, M2 implements I1 {} '''); } @@ -3326,16 +3328,12 @@ class Base { m(B a) {} } -// Note: no error reported in `extends Base` to avoid duplicating -// the error in T1. class T1 extends Base implements I1 { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } -// If there is no error in the class, we do report the error at -// the base class: -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2 - /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base +class /*error:INCONSISTENT_INHERITANCE*/T2 + extends Base implements I1 {} '''); } @@ -3354,19 +3352,20 @@ class M { } class T1 extends Object with M implements I1 { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2 - extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/T2 + extends Object with M implements I1 {} -class /*error:INCONSISTENT_METHOD_INHERITANCE*/U2 - = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M +class /*error:INCONSISTENT_INHERITANCE*/U2 + = Object with M implements I1; '''); } + @failingTest test_noDuplicateReports_typeOverridesSomeMethodInMultipleInterfaces() async { await checkFile(''' class A {} @@ -3382,7 +3381,7 @@ abstract class I2 implements I1 { class Base {} class T1 implements I2 { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -3439,7 +3438,7 @@ abstract class C { n(B b); } abstract class D extends C { - /*error:INVALID_METHOD_OVERRIDE*/m(B b); + /*error:INVALID_OVERRIDE*/m(B b); n(A a); } '''); @@ -3464,19 +3463,15 @@ class D extends B implements A { } return checkFile(r''' abstract class A { void test(A arg) { } } abstract class B extends A { - /*error:INVALID_METHOD_OVERRIDE*/void test(B arg) { } + /*error:INVALID_OVERRIDE*/void test(B arg) { } } abstract class X implements A { } class C extends B {} -// We treat "with X" as asking for another check. -// This feels inconsistent. -class D /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends B with X { } +class /*error:INVALID_OVERRIDE*/D extends B with X { } -// We treat "implements A" as asking for another check. -// This feels inconsistent. -class E /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends B implements A { } +class /*error:INVALID_OVERRIDE*/E extends B implements A { } '''); } @@ -3498,7 +3493,7 @@ class GrandChild extends main.Child { var _f3; var _f4; - /*error:INVALID_METHOD_OVERRIDE*/String _m1() => null; + /*error:INVALID_OVERRIDE*/String _m1() => null; } ''', name: '/helper.dart'); await checkFile(''' @@ -3654,15 +3649,15 @@ class F { class G extends F { void set f(ToVoid x) {} - /*error:INVALID_METHOD_OVERRIDE*/void set g(ToVoid x) {} - /*error:INVALID_METHOD_OVERRIDE*/void set h(int x) {} + /*error:INVALID_OVERRIDE*/void set g(ToVoid x) {} + /*error:INVALID_OVERRIDE*/void set h(int x) {} void set i(dynamic x) {} } class H implements F { void set f(ToVoid x) {} - /*error:INVALID_METHOD_OVERRIDE*/void set g(ToVoid x) {} - /*error:INVALID_METHOD_OVERRIDE*/void set h(int x) {} + /*error:INVALID_OVERRIDE*/void set g(ToVoid x) {} + /*error:INVALID_OVERRIDE*/void set h(int x) {} void set i(dynamic x) {} } '''); @@ -3702,7 +3697,7 @@ abstract class Base { class Child extends Base { void set f1(A value) {} - /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {} + /*error:INVALID_OVERRIDE*/void set f2(C value) {} void set f3(value) {} void set f4(dynamic value) {} set f5(B value) {} @@ -3755,7 +3750,7 @@ abstract class I1 { } abstract class Base implements I1 { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } class T1 extends Base { @@ -3764,7 +3759,7 @@ class T1 extends Base { // TODO(sigmund): consider tracking overrides in a fine-grain // manner, then this and the double-overrides would not be // reported. - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -3779,11 +3774,11 @@ abstract class I1 { } class Base implements I1 { - /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } class T1 extends Base { - m(B a) {} + /*error:INVALID_OVERRIDE*/m(B a) {} } '''); } @@ -3802,8 +3797,8 @@ class Base { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I2 {} +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Base implements I2 {} '''); } @@ -3821,8 +3816,8 @@ class Base { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Base implements I2 {} '''); } @@ -3841,8 +3836,8 @@ class Base { m(B a) {} } -class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 - /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base +class /*error:INCONSISTENT_INHERITANCE*/T1 + extends Base implements I2 {} '''); } @@ -3872,7 +3867,7 @@ class C { } // This mixin application doesn't provide a valid superclass for B -class D extends C with /*error:INCONSISTENT_METHOD_INHERITANCE*/B {} +class D extends C with /*error:INCONSISTENT_INHERITANCE*/B {} } ''', superMixins: true); } @@ -4352,7 +4347,7 @@ class A { } class B extends A { - /*error:INVALID_METHOD_OVERRIDE*/T method(T x) => x; + /*error:INVALID_OVERRIDE*/T method(T x) => x; } '''); } @@ -4385,12 +4380,6 @@ class CheckerTest_Driver extends CheckerTest { @override bool get enableNewAnalysisDriver => true; - @failingTest - @override - test_covariantOverride_fields() async { - await super.test_covariantOverride_fields(); - } - @override // Passes with driver test_interfacesFromMixinsUsedTwiceAreChecked() => super.test_interfacesFromMixinsUsedTwiceAreChecked(); diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart index b2e2a7a2eb27f..d1137b6c99ca9 100644 --- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart +++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart @@ -431,12 +431,12 @@ class B { } class C1 implements A, B { - /*error:INVALID_METHOD_OVERRIDE*/get a => null; + /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/get a => null; } // Still ambiguous class C2 implements B, A { - /*error:INVALID_METHOD_OVERRIDE*/get a => null; + /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/get a => null; } '''); } @@ -468,7 +468,7 @@ class C1 implements A, B { } class C2 implements A, B { - /*error:INVALID_METHOD_OVERRIDE*/get a => null; + /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/get a => null; } '''); } @@ -751,7 +751,7 @@ class A { } class B implements A { - /*error:INVALID_METHOD_OVERRIDE*/dynamic get x => 3; + /*error:INVALID_OVERRIDE*/dynamic get x => 3; } foo() { @@ -1908,7 +1908,7 @@ class C { T m(T x) => x; } class D extends C { -/*error:INVALID_METHOD_OVERRIDE*/m(x) => x; +/*error:INVALID_OVERRIDE*/m(x) => x; } main() { int y = /*info:DYNAMIC_CAST*/new D()./*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/m(42); @@ -1955,8 +1955,8 @@ class C { dynamic g(int x) => x; } class D extends C { - /*error:INVALID_METHOD_OVERRIDE*/T m(T x) => x; - /*error:INVALID_METHOD_OVERRIDE*/T g(T x) => x; + /*error:INVALID_OVERRIDE*/T m(T x) => x; + /*error:INVALID_OVERRIDE*/T g(T x) => x; } main() { int y = /*info:DYNAMIC_CAST*/(/*info:UNNECESSARY_CAST*/new D() as C).m(42); @@ -3383,7 +3383,7 @@ class A { } class B implements A { - /*error:INVALID_METHOD_OVERRIDE*/dynamic get x => 3; + /*error:INVALID_OVERRIDE*/dynamic get x => 3; } foo() { diff --git a/pkg/analyzer_cli/test/strong_mode_test.dart b/pkg/analyzer_cli/test/strong_mode_test.dart index 30f7815208754..85a4928af3dae 100644 --- a/pkg/analyzer_cli/test/strong_mode_test.dart +++ b/pkg/analyzer_cli/test/strong_mode_test.dart @@ -30,7 +30,7 @@ class StrongModeTest extends BaseTest { expect(exitCode, 3); var stdout = bulletToDash(outSink); - expect(stdout, contains('error - Invalid override')); + expect(stdout, contains("isn't a valid override of")); expect(stdout, contains('error - The list literal type')); expect(stdout, contains('2 errors found')); } diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status index 65e23027f657c..e0f1d182fb993 100644 --- a/tests/language_2/language_2_analyzer.status +++ b/tests/language_2/language_2_analyzer.status @@ -5,8 +5,6 @@ # Sections in this file should contain "$compiler == dart2analyzer". [ $compiler == dart2analyzer ] -abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue #30568 -abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568 accessor_conflict_export2_test: CompileTimeError # Issue 25626 accessor_conflict_export_test: CompileTimeError # Issue 25626 accessor_conflict_import2_test: CompileTimeError # Issue 25626 @@ -14,6 +12,7 @@ accessor_conflict_import_prefixed2_test: CompileTimeError # Issue 25626 accessor_conflict_import_prefixed_test: CompileTimeError # Issue 25626 accessor_conflict_import_test: CompileTimeError # Issue 25626 additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568 +bug34235_test/01: Pass cascaded_forwarding_stubs_test: CompileTimeError # Issue 34329 config_import_corelib_test: CompileTimeError, StaticWarning, OK # failing-by-design: Will never pass, see Issue #34332 conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Issue #34333 (loops forever) @@ -71,6 +70,7 @@ issue31596_super_test/none: CompileTimeError # Issue #31596 issue31596_tearoff_test: CompileTimeError # Issue #31596 issue31596_test: CompileTimeError # Issue #31596 issue34498_test: MissingCompileTimeError # Issue 34500 +large_class_declaration_test: Slow, Pass malformed2_test: Pass, MissingCompileTimeError # Flaky: issue 31056. mixin_declaration/mixin_declaration_inference_invalid_07_test: MissingCompileTimeError mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError # Issue 30552 @@ -108,8 +108,6 @@ regress_29405_test: CompileTimeError # Issue 29421 regress_29784_test/02: MissingCompileTimeError # Issue 29784 regress_30121_test: CompileTimeError # Issue 31087 regress_30339_test: CompileTimeError -regress_32660_test/01: MissingCompileTimeError # Issue #32660. -regress_32660_test/04: CompileTimeError regress_33479_test/01: Crash # Issue #33479 setter3_test/01: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837 setter3_test/02: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837 diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status index c9f79bb41b1e8..776f8959c05a8 100644 --- a/tests/language_2/language_2_dartdevc.status +++ b/tests/language_2/language_2_dartdevc.status @@ -4,8 +4,6 @@ # Sections in this file should contain "$compiler == dartdevc" or dartdevk. [ $compiler == dartdevc ] -abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue #30568 -abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568 accessor_conflict_export2_test: CompileTimeError # Issue 25626 accessor_conflict_export_test: CompileTimeError # Issue 25626 accessor_conflict_import2_test: CompileTimeError # Issue 25626 @@ -22,6 +20,7 @@ async_star_test/none: RuntimeError await_future_test: Pass, Timeout # Issue 29920 bit_operations_test: RuntimeError # No bigints on web. bug32372_test: RuntimeError +bug34235_test/01: Pass built_in_identifier_prefix_test: CompileTimeError built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 28816 built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 28816 @@ -105,6 +104,7 @@ issue34404_flutter_modified_test: CompileTimeError # DDC doesn't support mixin i issue34404_flutter_test: CompileTimeError # DDC doesn't support mixin inference issue34498_test: MissingCompileTimeError # Issue 34500 label_test: RuntimeError +large_class_declaration_test: Slow, Pass left_shift_test: RuntimeError # Ints and doubles are unified. mixin_declaration/mixin_declaration_inference_invalid_03_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 mixin_declaration/mixin_declaration_inference_invalid_04_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 @@ -181,8 +181,6 @@ regress_29784_test/02: Crash # assert initializers not implemented regress_29784_test/02: MissingCompileTimeError regress_30121_test: CompileTimeError # Issue 31087 regress_30339_test: CompileTimeError # As expected. Should we make this a multi test? -regress_32660_test/01: MissingCompileTimeError # Issue #32660. -regress_32660_test/04: CompileTimeError regress_33479_test/01: Crash # Issue #33479 setter3_test/01: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837 setter3_test/02: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837 diff --git a/tests/language_2/regress_34392_test.dart b/tests/language_2/regress_34392_test.dart new file mode 100644 index 0000000000000..286d8e134743d --- /dev/null +++ b/tests/language_2/regress_34392_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2018, 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. + +abstract class I { + foo([a]); +} + +abstract class A { + foo() {} +} + +abstract class B extends A implements I {} + +class C extends B { + foo([a]) {} +} + +void main() {}