From 95d37b0921f515b65d3febeaad08026045f1443f Mon Sep 17 00:00:00 2001 From: Zach Anderson Date: Mon, 24 Sep 2018 21:27:34 +0000 Subject: [PATCH] Revert "Implement inheritance/override checks from the spec." This reverts commit 836a1d7a881694ef15720f81e7c0dc1f392135d4. Revert "Don't use ClassElementImpl for now in override checking." This reverts commit 58e44c1400d2c6f395e5fc995b1fe9f4cc3a3676. Revert "large_class_declaration_test is slow now." This reverts commit 56f6c52d58d471dced76b3f84eb9fed0761b1c88. Revert "Add regression test for issue 34392." This reverts commit ef7d144bc7e685c06f021ce4da3a1276106723d3. Revert "Mixin declarations don't have supertype, fix isMoreSpecificThan()." This reverts commit 95b8a19a20d111d4a43d8d6da830b1795b919e67. Change-Id: Icda9cf9091ef35acc8fd61ac5dc135b3717eba0a Reviewed-on: https://dart-review.googlesource.com/76301 Reviewed-by: Konstantin Shcheglov Commit-Queue: Zach Anderson --- pkg/analyzer/lib/error/error.dart | 15 +- .../src/dart/analysis/library_analyzer.dart | 23 +- pkg/analyzer/lib/src/dart/element/type.dart | 25 +- .../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 +- .../generated/non_error_resolver_test.dart | 7 +- .../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 | 52 +-- .../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 | 5 +- tests/language_2/language_2_dartdevc.status | 27 +- tests/language_2/regress_34392_test.dart | 19 - 25 files changed, 1034 insertions(+), 845 deletions(-) delete mode 100644 pkg/analyzer/lib/src/error/inheritance_override.dart delete 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 24350132f992..7292017b7589 100644 --- a/pkg/analyzer/lib/error/error.dart +++ b/pkg/analyzer/lib/error/error.dart @@ -145,8 +145,6 @@ 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, @@ -166,7 +164,6 @@ 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, @@ -535,6 +532,7 @@ 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, @@ -593,6 +591,14 @@ 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, @@ -668,6 +674,9 @@ 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 6fe57fe9e5dc..3de1ee3bd3fb 100644 --- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart +++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart @@ -19,7 +19,6 @@ 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'; @@ -295,13 +294,14 @@ class LibraryAnalyzer { RecordingErrorListener errorListener = _getErrorListener(file); AnalysisOptionsImpl options = _analysisOptions as AnalysisOptionsImpl; - var typeSystem = new StrongTypeSystemImpl(_typeProvider, - implicitCasts: options.implicitCasts, - declarationCasts: options.declarationCasts, - nonnullableTypes: options.nonnullableTypes); - - CodeChecker checker = - new CodeChecker(_typeProvider, typeSystem, errorListener, options); + CodeChecker checker = new CodeChecker( + _typeProvider, + new StrongTypeSystemImpl(_typeProvider, + implicitCasts: options.implicitCasts, + declarationCasts: options.declarationCasts, + nonnullableTypes: options.nonnullableTypes), + errorListener, + options); checker.visitCompilationUnit(unit); ErrorReporter errorReporter = _getErrorReporter(file); @@ -316,13 +316,6 @@ 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 71c1338b19d3..178000f43719 100644 --- a/pkg/analyzer/lib/src/dart/element/type.dart +++ b/pkg/analyzer/lib/src/dart/element/type.dart @@ -1508,11 +1508,9 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { // List jArgs = j.typeArguments; List jVars = jElement.type.typeArguments; - if (supertype != null) { - supertype = supertype.substitute2(jArgs, jVars); - if (supertype == i) { - return true; - } + supertype = supertype.substitute2(jArgs, jVars); + if (supertype == i) { + return true; } // // I is listed in the on clause of J. @@ -1766,16 +1764,13 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { } ExecutableElement lookUpInheritedMember(String name, LibraryElement library, - {bool concrete: false, - int startMixinIndex, - bool setter: false, - bool thisType: false}) { + {bool concrete: false, int stopMixinIndex, bool setter: false}) { HashSet visitedClasses = new HashSet(); ExecutableElement lookUpImpl(InterfaceTypeImpl type, {bool acceptAbstract: false, bool includeType: true, - int startMixinIndex}) { + int stopMixinIndex}) { if (type == null || !visitedClasses.add(type.element)) { return null; } @@ -1801,8 +1796,10 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { } var mixins = type.mixins; - startMixinIndex ??= mixins.length; - for (var i = startMixinIndex - 1; i >= 0; i--) { + 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; @@ -1834,8 +1831,8 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType { } else { return lookUpImpl( this, - includeType: thisType, - startMixinIndex: startMixinIndex, + includeType: false, + stopMixinIndex: stopMixinIndex, ); } } diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart index 2a4d371a0049..db3945b11b8e 100644 --- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart +++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart @@ -15,6 +15,7 @@ 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'; @@ -715,10 +716,34 @@ 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]. + * by [classElt]. Also report static warnings + * [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE] and + * [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD] if appropriate. * * @param classElt the class element to query. * @param unionMap a mapping from method name to the set of unique (in terms of signature) methods @@ -813,7 +838,38 @@ class InheritanceManager { // resultMap[key] = elements[subtypesOfAllOtherTypesIndexes[0]]; } else { - if (!subtypesOfAllOtherTypesIndexes.isEmpty) { + 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 { // // Example: class A inherits 2 methods named 'm'. // One has the function type '(int) -> dynamic' and one has the @@ -840,6 +896,12 @@ 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 b1d42a6eadb7..37b838cbf89c 100644 --- a/pkg/analyzer/lib/src/error/codes.dart +++ b/pkg/analyzer/lib/src/error/codes.dart @@ -1260,46 +1260,6 @@ 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 @@ -1527,26 +1487,6 @@ 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 @@ -2855,6 +2795,41 @@ 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. @@ -3831,6 +3806,158 @@ 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 @@ -4585,6 +4712,9 @@ 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. * @@ -4700,6 +4830,23 @@ 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 deleted file mode 100644 index 1d48cf740367..000000000000 --- a/pkg/analyzer/lib/src/error/inheritance_override.dart +++ /dev/null @@ -1,384 +0,0 @@ -// 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 3c84e61fa3e5..eb1268651202 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( - CompileTimeErrorCode.INVALID_OVERRIDE, offset, length); + StrongModeCode.INVALID_METHOD_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 39d92e27f685..f36c11849ec8 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, - startMixinIndex: mixinIndex, + stopMixinIndex: 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 637d3fa730ec..1cedd7a0466c 100644 --- a/pkg/analyzer/lib/src/task/dart.dart +++ b/pkg/analyzer/lib/src/task/dart.dart @@ -26,7 +26,6 @@ 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,14 +5552,6 @@ 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 efe990e8f0dd..74f65da65d93 100644 --- a/pkg/analyzer/lib/src/task/strong/checker.dart +++ b/pkg/analyzer/lib/src/task/strong/checker.dart @@ -95,6 +95,33 @@ 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) { @@ -1249,8 +1276,11 @@ class CodeChecker extends RecursiveAstVisitor { /// applications. class _OverrideChecker { final StrongTypeSystemImpl rules; + final CodeChecker _checker; - _OverrideChecker(CodeChecker checker) : rules = checker.rules; + _OverrideChecker(CodeChecker checker) + : _checker = checker, + rules = checker.rules; void check(Declaration node) { var element = @@ -1258,6 +1288,9 @@ class _OverrideChecker { if (element.type.isObject) { return; } + _checkSuperOverrides(node, element); + _checkMixinApplicationOverrides(node, element); + _checkAllInterfaceOverrides(node, element); _checkForCovariantGenerics(node, element); } @@ -1535,6 +1568,133 @@ 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). /// @@ -1579,11 +1739,196 @@ 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 dbfb8a2ace96..724f3b8c46f7 100644 --- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart +++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart @@ -2649,20 +2649,10 @@ 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); - 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 - ]); - } + assertErrors(source, [ + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS + ]); verify([source]); } @@ -2732,20 +2722,10 @@ class A {} class M {} class C = A with M implements String, num;'''); await computeAnalysisResult(source); - 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 - ]); - } + assertErrors(source, [ + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, + CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS + ]); verify([source]); } @@ -4251,18 +4231,14 @@ class C = A with String;'''); class A {} class C = A with String, num;'''); await computeAnalysisResult(source); - if (enableNewAnalysisDriver) { + if (previewDart2) { assertErrors(source, [ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, - CompileTimeErrorCode.INVALID_OVERRIDE, + StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_MIXIN, 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_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart index 463e686bb55e..d224d7f77f09 100644 --- a/pkg/analyzer/test/generated/non_error_resolver_test.dart +++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart @@ -4458,12 +4458,7 @@ class A { class C {} class B extends A with C {}'''); await computeAnalysisResult(source); - if (previewDart2) { - assertErrors( - source, - [CompileTimeErrorCode.INVALID_OVERRIDE], - ); - } + assertNoErrors(source); verify([source]); } diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart index 208b63789fd0..a6873453b2a1 100644 --- a/pkg/analyzer/test/generated/non_hint_code_test.dart +++ b/pkg/analyzer/test/generated/non_hint_code_test.dart @@ -658,10 +658,7 @@ class B implements A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors( - source, - [CompileTimeErrorCode.INVALID_OVERRIDE], - ); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertNoErrors(source); } @@ -685,10 +682,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors( - source, - [CompileTimeErrorCode.INVALID_OVERRIDE], - ); + assertErrors(source, [StrongModeCode.INVALID_METHOD_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 825e0fb031fd..5003da0e499d 100644 --- a/pkg/analyzer/test/generated/static_warning_code_test.dart +++ b/pkg/analyzer/test/generated/static_warning_code_test.dart @@ -1859,7 +1859,12 @@ class B extends A { String get g { return 'a'; } }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -1872,10 +1877,17 @@ class B extends A { int f; }'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + 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 + ]); + } verify([source]); } @@ -1893,10 +1905,12 @@ class B extends A { String get getter => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE, - ]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -1912,10 +1926,12 @@ class B implements I, J { double get g => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -1928,7 +1944,12 @@ class B implements A { m({String a}) {} }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE]); + } verify([source]); } @@ -1941,7 +1962,12 @@ class B implements A { m(String a) {} }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors(source, + [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); + } verify([source]); } @@ -1954,7 +1980,12 @@ class B extends A { m(String a) {} }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors(source, + [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); + } verify([source]); } @@ -1970,10 +2001,15 @@ class B extends I implements J { m(double d) {} }'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + if (previewDart2) { + assertErrors(source, [ + StrongModeCode.INVALID_METHOD_OVERRIDE, + StrongModeCode.INVALID_METHOD_OVERRIDE + ]); + } else { + assertErrors(source, + [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); + } verify([source]); } @@ -1990,10 +2026,12 @@ class B extends A { m(String n) {} }'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors(source, + [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); + } verify([source]); } @@ -2010,10 +2048,12 @@ class B implements I, J { m(double d) {} }'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors(source, + [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]); + } verify([source]); } @@ -2026,7 +2066,12 @@ class B implements A { m([String a]) {} }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors(source, + [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]); + } verify([source]); } @@ -2043,10 +2088,12 @@ class B extends A { m([String n]) {} }'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors(source, + [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]); + } verify([source]); } @@ -2059,7 +2106,12 @@ class B implements A { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -2074,7 +2126,12 @@ class C implements B { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -2087,7 +2144,12 @@ class B extends Object with A { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -2100,7 +2162,12 @@ class B extends A { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -2115,7 +2182,12 @@ class C extends B { String m() { return 'a'; } }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -2132,10 +2204,12 @@ class B extends A { String m() => ''; }'''); await computeAnalysisResult(source); - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -2148,7 +2222,12 @@ class B extends A { void m() {} }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); + } else { + assertErrors( + source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE]); + } verify([source]); } @@ -2314,7 +2393,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_NAMED]); } @@ -2331,7 +2410,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_NAMED]); } @@ -2348,7 +2427,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]); } @@ -2365,7 +2444,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]); } @@ -2382,7 +2461,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]); } @@ -2399,7 +2478,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_REQUIRED]); } @@ -2416,7 +2495,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]); @@ -2439,8 +2518,9 @@ class B extends A { await computeAnalysisResult(source); if (previewDart2) { assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE, + StrongModeCode.INVALID_METHOD_OVERRIDE, + StrongModeCode.INVALID_METHOD_OVERRIDE, + StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_BASE ]); } else { assertErrors(source, @@ -2464,10 +2544,7 @@ class B extends A { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]); @@ -2488,10 +2565,7 @@ class B implements I, J { }'''); await computeAnalysisResult(source); if (previewDart2) { - assertErrors(source, [ - CompileTimeErrorCode.INVALID_OVERRIDE, - CompileTimeErrorCode.INVALID_OVERRIDE - ]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); } else { assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]); @@ -2849,7 +2923,12 @@ abstract class D { } class E extends C implements D {}'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + if (previewDart2) { + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE_FROM_BASE]); + } else { + assertErrors(source, + [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]); + } verify([source]); } diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart index d302e2f9b830..0456a6fbbae5 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, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); verify([source]); } @@ -3475,7 +3475,7 @@ class D extends C { T f(T x) => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); verify([source]); } @@ -3488,7 +3488,7 @@ class D extends C { String f(S x) => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]); verify([source]); } @@ -3501,7 +3501,7 @@ class D extends C { S f(T x) => null; }'''); await computeAnalysisResult(source); - assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]); + assertErrors(source, [StrongModeCode.INVALID_METHOD_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 1cac15e049c8..e617b6891292 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_inconsistentInheritance_parameterType() async { + test_inconsistentMethodInheritance_parameterType() async { addTestFile(r''' abstract class A { x(int i); @@ -1303,11 +1303,11 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritance_requiredParameters() async { + test_inconsistentMethodInheritance_requiredParameters() async { addTestFile(r''' abstract class A { x(); @@ -1319,11 +1319,11 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritance_returnType() async { + test_inconsistentMethodInheritance_returnType() async { addTestFile(r''' abstract class A { int x(); @@ -1335,11 +1335,11 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritanceGetterAndMethod_getter_method() async { + test_inconsistentMethodInheritanceGetterAndMethod_getter_method() async { addTestFile(r''' abstract class A { int get x; @@ -1351,11 +1351,11 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, + StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentInheritanceGetterAndMethod_method_getter() async { + test_inconsistentMethodInheritanceGetterAndMethod_method_getter() async { addTestFile(r''' abstract class A { int x(); @@ -1367,7 +1367,7 @@ abstract class C implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, + StaticWarningCode.INCONSISTENT_METHOD_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 2c27d0d8e02e..0375fc22e73b 100644 --- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart @@ -1419,7 +1419,7 @@ mixin M implements A, B {} // M assertTypeName(bRef, findElement.class_('B'), 'B'); } - test_inconsistentInheritance_implements_parameterType() async { + test_inconsistentMethodInheritance_implements_parameterType() async { addTestFile(r''' abstract class A { x(int i); @@ -1431,11 +1431,11 @@ mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritance_implements_requiredParameters() async { + test_inconsistentMethodInheritance_implements_requiredParameters() async { addTestFile(r''' abstract class A { x(); @@ -1447,11 +1447,11 @@ mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritance_implements_returnType() async { + test_inconsistentMethodInheritance_implements_returnType() async { addTestFile(r''' abstract class A { int x(); @@ -1463,11 +1463,11 @@ mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritance_on_parameterType() async { + test_inconsistentMethodInheritance_on_parameterType() async { addTestFile(r''' abstract class A { x(int i); @@ -1479,11 +1479,11 @@ mixin M on A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritance_on_requiredParameters() async { + test_inconsistentMethodInheritance_on_requiredParameters() async { addTestFile(r''' abstract class A { x(); @@ -1495,11 +1495,11 @@ mixin M on A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritance_on_returnType() async { + test_inconsistentMethodInheritance_on_returnType() async { addTestFile(r''' abstract class A { int x(); @@ -1511,11 +1511,11 @@ mixin M on A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE, + StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, ]); } - test_inconsistentInheritanceGetterAndMethod_implements_getter_method() async { + test_inconsistentMethodInheritanceGetterAndMethod_implements_getter_method() async { addTestFile(r''' abstract class A { int get x; @@ -1527,11 +1527,11 @@ mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, + StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentInheritanceGetterAndMethod_implements_method_getter() async { + test_inconsistentMethodInheritanceGetterAndMethod_implements_method_getter() async { addTestFile(r''' abstract class A { int x(); @@ -1543,11 +1543,11 @@ mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, + StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentInheritanceGetterAndMethod_on_getter_method() async { + test_inconsistentMethodInheritanceGetterAndMethod_on_getter_method() async { addTestFile(r''' abstract class A { int get x; @@ -1559,11 +1559,11 @@ mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, + StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, ]); } - test_inconsistentInheritanceGetterAndMethod_on_method_getter() async { + test_inconsistentMethodInheritanceGetterAndMethod_on_method_getter() async { addTestFile(r''' abstract class A { int x(); @@ -1575,22 +1575,10 @@ mixin M implements A, B {} '''); await resolveTestFile(); assertTestErrors([ - CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD, + StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, ]); } - test_isMoreSpecificThan() async { - addTestFile(r''' -mixin M {} -'''); - await resolveTestFile(); - assertNoTestErrors(); - - var element = findElement.mixin('M'); - var type = element.type; - expect(type.isMoreSpecificThan(intType), isFalse); - } - test_metadata() async { addTestFile(r''' const a = 0; 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 65921c71ce90..939596cf9ec0 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_OVERRIDE,error:INVALID_OVERRIDE*/var aaa; + /*error:INVALID_METHOD_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 e00db4fca649..e2a86820eed2 100644 --- a/pkg/analyzer/test/src/task/options_test.dart +++ b/pkg/analyzer/test/src/task/options_test.dart @@ -227,6 +227,9 @@ 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 0bce85aa5c59..994a8bd572c3 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_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } '''); } @@ -190,7 +190,10 @@ class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base implements I1 {} class T1 extends Base { - /*error:INVALID_OVERRIDE*/m(B a) {} + // 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) {} } '''); } @@ -206,7 +209,7 @@ abstract class I1 { abstract class I2 implements I1 {} class T1 implements I2 { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } '''); } @@ -222,7 +225,7 @@ abstract class M1 { abstract class I2 extends Object with M1 {} class T1 implements I2 { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } '''); } @@ -238,7 +241,7 @@ abstract class I1 { abstract class I2 extends I1 {} class T1 implements I2 { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } '''); } @@ -543,21 +546,20 @@ class F extends E { class G extends E implements D {} class D_error extends C { - /*error:INVALID_OVERRIDE*/int f(int x) => x; + /*error:INVALID_METHOD_OVERRIDE*/int f(int x) => x; } class E_error extends D { - /*error:INVALID_OVERRIDE*/int f(@checked double x) => 0; + /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0; } class F_error extends E { - /*error:INVALID_OVERRIDE*/int f(@checked double x) => 0; + /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0; } class G_error extends E implements D { - /*error:INVALID_OVERRIDE*/int f(@checked double x) => 0; + /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0; } '''); } - @failingTest test_covariantOverride_fields() async { _addMetaLibrary(); await checkFile(r''' @@ -577,7 +579,7 @@ class D extends C { @virtual int foo; } class E extends D { - @virtual num foo; + @virtual /*error:INVALID_METHOD_OVERRIDE*/num foo; } '''); } @@ -626,16 +628,16 @@ class F extends E { class G extends E implements D {} class D_error extends C { - /*error:INVALID_OVERRIDE*/int f(String x) => 0; + /*error:INVALID_METHOD_OVERRIDE*/int f(String x) => 0; } class E_error extends D { - /*error:INVALID_OVERRIDE*/int f(double x) => 0; + /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0; } class F_error extends E { - /*error:INVALID_OVERRIDE*/int f(double x) => 0; + /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0; } class G_error extends E implements D { - /*error:INVALID_OVERRIDE*/int f(double x) => 0; + /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0; } '''); } @@ -728,17 +730,17 @@ class Base { } class Child extends Base { - /*error:INVALID_OVERRIDE*/A f1; // invalid for getter - /*error:INVALID_OVERRIDE*/C f2; // invalid for setter + /*error:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter + /*error:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter var f3; - /*error:INVALID_OVERRIDE*/dynamic f4; + /*error:INVALID_METHOD_OVERRIDE*/dynamic f4; } class Child2 implements Base { - /*error:INVALID_OVERRIDE*/A f1; // invalid for getter - /*error:INVALID_OVERRIDE*/C f2; // invalid for setter + /*error:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter + /*error:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter var f3; - /*error:INVALID_OVERRIDE*/dynamic f4; + /*error:INVALID_METHOD_OVERRIDE*/dynamic f4; } '''); } @@ -757,17 +759,17 @@ abstract class Base { } class Child extends Base { - /*error:INVALID_OVERRIDE*/A get f1 => null; + /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null; C get f2 => null; get f3 => null; - /*error:INVALID_OVERRIDE*/dynamic get f4 => null; + /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null; } class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implements Base { - /*error:INVALID_OVERRIDE*/A get f1 => null; + /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null; C get f2 => null; get f3 => null; - /*error:INVALID_OVERRIDE*/dynamic get f4 => null; + /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null; } '''); } @@ -781,12 +783,12 @@ class F { } class G extends F { - /*error:INVALID_OVERRIDE*/final ToVoid f = null; + /*error:INVALID_METHOD_OVERRIDE*/final ToVoid f = null; final ToVoid g = null; } class H implements F { - /*error:INVALID_OVERRIDE*/final ToVoid f = null; + /*error:INVALID_METHOD_OVERRIDE*/final ToVoid f = null; final ToVoid g = null; } '''); @@ -844,7 +846,7 @@ class Child extends Base { B get f5 => null; void set f1(A value) {} - /*error:INVALID_OVERRIDE*/void set f2(C value) {} + /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {} void set f3(value) {} void set f4(dynamic value) {} set f5(B value) {} @@ -858,7 +860,7 @@ class Child2 implements Base { B get f5 => null; void set f1(A value) {} - /*error:INVALID_OVERRIDE*/void set f2(C value) {} + /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {} void set f3(value) {} void set f4(dynamic value) {} set f5(B value) {} @@ -1964,7 +1966,7 @@ class Base { } class Derived extends Base { - /*error:INVALID_OVERRIDE*/S foo() => null; + /*error:INVALID_METHOD_OVERRIDE*/S foo() => null; } class Derived2 extends Base { @@ -2072,10 +2074,10 @@ abstract class Base { } class Child extends Base { - /*error:INVALID_OVERRIDE*/A get f1 => null; + /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null; C get f2 => null; get f3 => null; - /*error:INVALID_OVERRIDE*/dynamic get f4 => null; + /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null; } '''); } @@ -2090,12 +2092,12 @@ class F { } class G extends F { - /*error:INVALID_OVERRIDE*/ToVoid get f => null; + /*error:INVALID_METHOD_OVERRIDE*/ToVoid get f => null; ToVoid get g => null; } class H implements F { - /*error:INVALID_OVERRIDE*/ToVoid get f => null; + /*error:INVALID_METHOD_OVERRIDE*/ToVoid get f => null; ToVoid get g => null; } '''); @@ -2550,7 +2552,7 @@ class C { set x(Object y) {} } class D implements B, C { - /*error:INVALID_OVERRIDE*/int x; + /*error:INVALID_METHOD_OVERRIDE*/int x; } '''); } @@ -2564,13 +2566,13 @@ abstract class I { abstract class M implements I {} class C extends Object with M { - /*error:INVALID_OVERRIDE*/String x; + /*error:INVALID_METHOD_OVERRIDE*/String x; } abstract class M2 = Object with M; class C2 extends Object with M2 { - /*error:INVALID_OVERRIDE*/String x; + /*error:INVALID_METHOD_OVERRIDE*/String x; } '''); } @@ -2601,13 +2603,13 @@ abstract class I { abstract class M implements I {} class C extends Object with M { - /*error:INVALID_OVERRIDE*/String x; + /*error:INVALID_METHOD_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_OVERRIDE*/int x; + /*error:INVALID_METHOD_OVERRIDE*/int x; } /*error:CONFLICTING_GENERIC_INTERFACES*/ /*error:CONFLICTING_GENERIC_INTERFACES*/class F extends D with M { @@ -2629,8 +2631,8 @@ class Base { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Base implements I {} +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I {} '''); } @@ -2644,37 +2646,37 @@ class Base { } class T1 extends Base { - /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,error:INVALID_OVERRIDE*/B get f => null; + /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,error:INVALID_METHOD_OVERRIDE*/B get f => null; } class T2 extends Base { - /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,error:INVALID_OVERRIDE*/set f( + /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,error:INVALID_METHOD_OVERRIDE*/set f( B b) => null; } class T3 extends Base { - /*error:INVALID_OVERRIDE*/final B + /*error:INVALID_METHOD_OVERRIDE*/final B /*error:FINAL_NOT_INITIALIZED*/f; } class T4 extends Base { // two: one for the getter one for the setter. - /*error:INVALID_OVERRIDE, error:INVALID_OVERRIDE*/B f; + /*error:INVALID_METHOD_OVERRIDE, error:INVALID_METHOD_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_OVERRIDE*/B get f => null; + /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_METHOD_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_OVERRIDE*/set f(B b) => null; + /*error:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_METHOD_OVERRIDE*/set f(B b) => null; } class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Base { - /*error:INVALID_OVERRIDE*/final B f = null; + /*error:INVALID_METHOD_OVERRIDE*/final B f = null; } class T8 implements Base { // two: one for the getter one for the setter. - /*error:INVALID_OVERRIDE, error:INVALID_OVERRIDE*/B f; + /*error:INVALID_METHOD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/B f; } '''); } @@ -2689,7 +2691,7 @@ class Base { } class Test extends Base { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } '''); } @@ -2704,12 +2706,11 @@ abstract class I { } class T1 implements I { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } '''); } - @failingTest test_invalidOverrides_doubleOverride() async { await checkFile(''' class A {} @@ -2724,12 +2725,11 @@ class Parent extends Grandparent { class Test extends Parent { // Reported only once - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_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_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } class Test extends Parent { @@ -2761,7 +2761,7 @@ class Parent extends Grandparent { } class Test extends Parent { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} int x; } '''); @@ -2780,12 +2780,12 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I {} -class /*error:INCONSISTENT_INHERITANCE*/U1 = Object - with M implements I; +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Object + with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I; '''); } @@ -2807,20 +2807,20 @@ class M2 { int x; } -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*/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*/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; +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; '''); } @@ -2842,17 +2842,16 @@ class M2 { int x; } -class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base with M1, - /*error:INVALID_OVERRIDE*/M2 {} + /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2 {} -class /*error:INCONSISTENT_INHERITANCE*/U1 = Base +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base with M1, - /*error:INVALID_OVERRIDE*/M2; + /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/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, @@ -2877,11 +2876,11 @@ class M3 { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base - with M1, /*error:INVALID_OVERRIDE_FROM_MIXIN*/M2, M3 {} +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends 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; +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base + with M1, /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2, M3; '''); } @@ -2900,20 +2899,20 @@ class I1 { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Base +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I1 {} class T2 extends Base implements I1 { m(a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T3 - extends Object with Base +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T3 + extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/Base implements I1 {} -class /*error:INCONSISTENT_INHERITANCE*/U3 - = Object with Base +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U3 + = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/Base implements I1; class T4 extends Object with Base implements I1 { @@ -3051,12 +3050,12 @@ class Base { } class Child extends Base { - /*error:INVALID_OVERRIDE*/A m1(A value) => null; - /*error:INVALID_OVERRIDE*/C m2(C value) => null; - /*error:INVALID_OVERRIDE*/A m3(C value) => null; + /*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; C m4(A value) => null; m5(value) => null; - /*error:INVALID_OVERRIDE*/dynamic m6(dynamic value) => null; + /*error:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) => null; } '''); } @@ -3075,12 +3074,12 @@ class F { } class G extends F { - /*error:INVALID_OVERRIDE*/void f(int x) {} + /*error:INVALID_METHOD_OVERRIDE*/void f(int x) {} void g(dynamic x) {} } class H implements F { - /*error:INVALID_OVERRIDE*/void f(int x) {} + /*error:INVALID_METHOD_OVERRIDE*/void f(int x) {} void g(dynamic x) {} } '''); @@ -3110,7 +3109,7 @@ class B { class C = Object with B; -class /*error:INVALID_OVERRIDE*/D extends Object with C implements A {} +class D extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/C implements A {} '''); } @@ -3128,11 +3127,11 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base - with /*error:INVALID_OVERRIDE*/M {} +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base + with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M {} -class /*error:INCONSISTENT_INHERITANCE*/U1 = Base - with /*error:INVALID_OVERRIDE*/M; +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base + with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M; '''); } @@ -3152,11 +3151,9 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 extends Base - with /*error:INVALID_OVERRIDE*/M {} +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base with M {} -class /*error:INCONSISTENT_INHERITANCE*/U1 = Base - with /*error:INVALID_OVERRIDE*/M; +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base with M; '''); } @@ -3174,12 +3171,12 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I2 {} -class /*error:INCONSISTENT_INHERITANCE*/U1 - = Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 + = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I2; '''); } @@ -3198,12 +3195,12 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I2 {} -class /*error:INCONSISTENT_INHERITANCE*/U1 - = Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 + = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I2; '''); } @@ -3222,12 +3219,12 @@ class M { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I2 {} -class /*error:INCONSISTENT_INHERITANCE*/U1 - = Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 + = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I2; '''); } @@ -3252,14 +3249,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_INHERITANCE*/T1 +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base - with M + with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I1 {} -class /*error:INCONSISTENT_INHERITANCE*/U1 = +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U1 = Base - with M + with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I1; '''); } @@ -3283,11 +3280,11 @@ class Parent1 extends Grandparent { class Parent2 extends Grandparent {} // Note: otherwise both errors would be reported on this line -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Parent1 +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent1 implements I1 {} -class /*error:INCONSISTENT_INHERITANCE*/T2 - extends Parent2 +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2 + /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent2 implements I1 {} '''); } @@ -3309,8 +3306,9 @@ class M2 { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 extends Object - with M1, M2 +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Object + with M1, + /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2 implements I1 {} '''); } @@ -3328,12 +3326,16 @@ 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_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T2 - extends Base +// 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 implements I1 {} '''); } @@ -3352,20 +3354,19 @@ class M { } class T1 extends Object with M implements I1 { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T2 - extends Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2 + extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I1 {} -class /*error:INCONSISTENT_INHERITANCE*/U2 - = Object with M +class /*error:INCONSISTENT_METHOD_INHERITANCE*/U2 + = Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M implements I1; '''); } - @failingTest test_noDuplicateReports_typeOverridesSomeMethodInMultipleInterfaces() async { await checkFile(''' class A {} @@ -3381,7 +3382,7 @@ abstract class I2 implements I1 { class Base {} class T1 implements I2 { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } '''); } @@ -3438,7 +3439,7 @@ abstract class C { n(B b); } abstract class D extends C { - /*error:INVALID_OVERRIDE*/m(B b); + /*error:INVALID_METHOD_OVERRIDE*/m(B b); n(A a); } '''); @@ -3463,15 +3464,19 @@ class D extends B implements A { } return checkFile(r''' abstract class A { void test(A arg) { } } abstract class B extends A { - /*error:INVALID_OVERRIDE*/void test(B arg) { } + /*error:INVALID_METHOD_OVERRIDE*/void test(B arg) { } } abstract class X implements A { } class C extends B {} -class /*error:INVALID_OVERRIDE*/D extends B with X { } +// 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*/E extends B implements A { } +// We treat "implements A" as asking for another check. +// This feels inconsistent. +class E /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends B implements A { } '''); } @@ -3493,7 +3498,7 @@ class GrandChild extends main.Child { var _f3; var _f4; - /*error:INVALID_OVERRIDE*/String _m1() => null; + /*error:INVALID_METHOD_OVERRIDE*/String _m1() => null; } ''', name: '/helper.dart'); await checkFile(''' @@ -3649,15 +3654,15 @@ class F { class G extends F { void set f(ToVoid x) {} - /*error:INVALID_OVERRIDE*/void set g(ToVoid x) {} - /*error:INVALID_OVERRIDE*/void set h(int x) {} + /*error:INVALID_METHOD_OVERRIDE*/void set g(ToVoid x) {} + /*error:INVALID_METHOD_OVERRIDE*/void set h(int x) {} void set i(dynamic x) {} } class H implements F { void set f(ToVoid x) {} - /*error:INVALID_OVERRIDE*/void set g(ToVoid x) {} - /*error:INVALID_OVERRIDE*/void set h(int x) {} + /*error:INVALID_METHOD_OVERRIDE*/void set g(ToVoid x) {} + /*error:INVALID_METHOD_OVERRIDE*/void set h(int x) {} void set i(dynamic x) {} } '''); @@ -3697,7 +3702,7 @@ abstract class Base { class Child extends Base { void set f1(A value) {} - /*error:INVALID_OVERRIDE*/void set f2(C value) {} + /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {} void set f3(value) {} void set f4(dynamic value) {} set f5(B value) {} @@ -3750,7 +3755,7 @@ abstract class I1 { } abstract class Base implements I1 { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } class T1 extends Base { @@ -3759,7 +3764,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_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } '''); } @@ -3774,11 +3779,11 @@ abstract class I1 { } class Base implements I1 { - /*error:INVALID_OVERRIDE*/m(B a) {} + /*error:INVALID_METHOD_OVERRIDE*/m(B a) {} } class T1 extends Base { - /*error:INVALID_OVERRIDE*/m(B a) {} + m(B a) {} } '''); } @@ -3797,8 +3802,8 @@ class Base { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Base implements I2 {} +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I2 {} '''); } @@ -3816,8 +3821,8 @@ class Base { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Base +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I2 {} '''); } @@ -3836,8 +3841,8 @@ class Base { m(B a) {} } -class /*error:INCONSISTENT_INHERITANCE*/T1 - extends Base +class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 + /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I2 {} '''); } @@ -3867,7 +3872,7 @@ class C { } // This mixin application doesn't provide a valid superclass for B -class D extends C with /*error:INCONSISTENT_INHERITANCE*/B {} +class D extends C with /*error:INCONSISTENT_METHOD_INHERITANCE*/B {} } ''', superMixins: true); } @@ -4347,7 +4352,7 @@ class A { } class B extends A { - /*error:INVALID_OVERRIDE*/T method(T x) => x; + /*error:INVALID_METHOD_OVERRIDE*/T method(T x) => x; } '''); } @@ -4380,6 +4385,12 @@ 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 d1137b6c99ca..b2e2a7a2eb27 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_OVERRIDE,error:INVALID_OVERRIDE*/get a => null; + /*error:INVALID_METHOD_OVERRIDE*/get a => null; } // Still ambiguous class C2 implements B, A { - /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/get a => null; + /*error:INVALID_METHOD_OVERRIDE*/get a => null; } '''); } @@ -468,7 +468,7 @@ class C1 implements A, B { } class C2 implements A, B { - /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/get a => null; + /*error:INVALID_METHOD_OVERRIDE*/get a => null; } '''); } @@ -751,7 +751,7 @@ class A { } class B implements A { - /*error:INVALID_OVERRIDE*/dynamic get x => 3; + /*error:INVALID_METHOD_OVERRIDE*/dynamic get x => 3; } foo() { @@ -1908,7 +1908,7 @@ class C { T m(T x) => x; } class D extends C { -/*error:INVALID_OVERRIDE*/m(x) => x; +/*error:INVALID_METHOD_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_OVERRIDE*/T m(T x) => x; - /*error:INVALID_OVERRIDE*/T g(T x) => x; + /*error:INVALID_METHOD_OVERRIDE*/T m(T x) => x; + /*error:INVALID_METHOD_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_OVERRIDE*/dynamic get x => 3; + /*error:INVALID_METHOD_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 85a4928af3da..30f781520875 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("isn't a valid override of")); + expect(stdout, contains('error - Invalid override')); 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 7fdc504eee5b..0389ef8189f8 100644 --- a/tests/language_2/language_2_analyzer.status +++ b/tests/language_2/language_2_analyzer.status @@ -5,6 +5,8 @@ # 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 @@ -12,7 +14,6 @@ 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) @@ -70,7 +71,6 @@ 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 @@ -109,6 +109,7 @@ 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 072f0fca5dcd..ae94dee6ce5a 100644 --- a/tests/language_2/language_2_dartdevc.status +++ b/tests/language_2/language_2_dartdevc.status @@ -4,6 +4,8 @@ # 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 @@ -20,7 +22,6 @@ 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 @@ -104,17 +105,16 @@ 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 -mixin_declaration/mixin_declaration_inference_invalid_05_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 -mixin_declaration/mixin_declaration_inference_invalid_06_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 -mixin_declaration/mixin_declaration_inference_invalid_07_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 -mixin_declaration/mixin_declaration_inference_invalid_08_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 -mixin_declaration/mixin_declaration_inference_invalid_09_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 -mixin_declaration/mixin_declaration_inference_invalid_10_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 -mixin_declaration/mixin_declaration_inference_invalid_11_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 +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 +mixin_declaration/mixin_declaration_inference_invalid_05_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 +mixin_declaration/mixin_declaration_inference_invalid_06_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 +mixin_declaration/mixin_declaration_inference_invalid_07_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 +mixin_declaration/mixin_declaration_inference_invalid_08_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 +mixin_declaration/mixin_declaration_inference_invalid_09_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 +mixin_declaration/mixin_declaration_inference_invalid_10_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 +mixin_declaration/mixin_declaration_inference_invalid_11_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/34167 mixin_declaration/mixin_declaration_inference_valid_A00_test: CompileTimeError # Issue #34164 mixin_declaration/mixin_declaration_inference_valid_A01_test: CompileTimeError # Issue #34164 mixin_declaration/mixin_declaration_inference_valid_A02_test: CompileTimeError # Issue #34164 @@ -144,8 +144,8 @@ mixin_declaration/mixin_declaration_inference_valid_C10_test: CompileTimeError # mixin_declaration/mixin_declaration_inference_valid_C11_test: CompileTimeError # Issue #34164 mixin_declaration/mixin_declaration_inference_valid_C12_test: CompileTimeError # Issue #34164 mixin_declaration/mixin_declaration_inference_valid_C13_test: CompileTimeError # Issue #34164 -mixin_declaration/mixin_declaration_inference_valid_mixin_applications_test: CompileTimeError # https://github.com/dart-lang/sdk/issues/34164 -mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError # Analyzer chooses wrong(?) super method. +mixin_declaration/mixin_declaration_inference_valid_mixin_applications_test: CompileTimeError # https://github.com/dart-lang/sdk/issues/34164 +mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError # Analyzer chooses wrong(?) super method. mixin_method_override_test/01: MissingCompileTimeError # Issue 34235 mixin_super_2_test/01: MissingCompileTimeError mixin_super_2_test/03: MissingCompileTimeError @@ -182,6 +182,7 @@ 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 deleted file mode 100644 index 286d8e134743..000000000000 --- a/tests/language_2/regress_34392_test.dart +++ /dev/null @@ -1,19 +0,0 @@ -// 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() {}