| Index: pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| diff --git a/pkg/analyzer_experimental/lib/src/generated/resolver.dart b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| index 4ff1d00ae648eef688825b6089612d12e387c526..5e64ea1f9340982b330f0adf8af786a16788b25a 100644
|
| --- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| +++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
|
| @@ -3523,18 +3523,42 @@ class InheritanceManager {
|
| } else {
|
| resultMap = new Map<String, ExecutableElement>();
|
| }
|
| + InterfaceType supertype2 = classElt.supertype;
|
| + ClassElement superclassElement = supertype2 != null ? supertype2.element : null;
|
| List<InterfaceType> interfaces2 = classElt.interfaces;
|
| - if (interfaces2.length == 0) {
|
| + if (superclassElement == null || interfaces2.length == 0) {
|
| _interfaceLookup[classElt] = resultMap;
|
| return resultMap;
|
| }
|
| List<Map<String, ExecutableElement>> lookupMaps = new List<Map<String, ExecutableElement>>();
|
| + if (superclassElement != null) {
|
| + if (!visitedInterfaces.contains(superclassElement)) {
|
| + try {
|
| + javaSetAdd(visitedInterfaces, superclassElement);
|
| + lookupMaps.add(computeInterfaceLookupMap(superclassElement, visitedInterfaces));
|
| + } finally {
|
| + visitedInterfaces.remove(superclassElement);
|
| + }
|
| + } else {
|
| + Map<String, ExecutableElement> map = _interfaceLookup[classElt];
|
| + if (map != null) {
|
| + lookupMaps.add(map);
|
| + } else {
|
| + _interfaceLookup[superclassElement] = resultMap;
|
| + return resultMap;
|
| + }
|
| + }
|
| + }
|
| for (InterfaceType interfaceType in interfaces2) {
|
| ClassElement interfaceElement = interfaceType.element;
|
| if (interfaceElement != null) {
|
| if (!visitedInterfaces.contains(interfaceElement)) {
|
| - javaSetAdd(visitedInterfaces, interfaceElement);
|
| - lookupMaps.add(computeInterfaceLookupMap(interfaceElement, visitedInterfaces));
|
| + try {
|
| + javaSetAdd(visitedInterfaces, interfaceElement);
|
| + lookupMaps.add(computeInterfaceLookupMap(interfaceElement, visitedInterfaces));
|
| + } finally {
|
| + visitedInterfaces.remove(interfaceElement);
|
| + }
|
| } else {
|
| Map<String, ExecutableElement> map = _interfaceLookup[classElt];
|
| if (map != null) {
|
| @@ -3563,11 +3587,39 @@ class InheritanceManager {
|
| }
|
| }
|
| }
|
| + if (superclassElement != null) {
|
| + List<MethodElement> methods2 = superclassElement.methods;
|
| + for (MethodElement method in methods2) {
|
| + if (method.isAccessibleIn(_library) && !method.isStatic()) {
|
| + String key = method.name;
|
| + if (!unionMap.containsKey(key)) {
|
| + Set<ExecutableElement> set = new Set<ExecutableElement>();
|
| + javaSetAdd(set, method);
|
| + unionMap[key] = set;
|
| + } else {
|
| + javaSetAdd(unionMap[key], method);
|
| + }
|
| + }
|
| + }
|
| + List<PropertyAccessorElement> accessors2 = superclassElement.accessors;
|
| + for (PropertyAccessorElement accessor in accessors2) {
|
| + if (accessor.isAccessibleIn(_library) && !accessor.isStatic()) {
|
| + String key = accessor.name;
|
| + if (!unionMap.containsKey(key)) {
|
| + Set<ExecutableElement> set = new Set<ExecutableElement>();
|
| + javaSetAdd(set, accessor);
|
| + unionMap[key] = set;
|
| + } else {
|
| + javaSetAdd(unionMap[key], accessor);
|
| + }
|
| + }
|
| + }
|
| + }
|
| for (InterfaceType interfaceType in interfaces2) {
|
| ClassElement interfaceElement = interfaceType.element;
|
| if (interfaceElement != null) {
|
| - List<MethodElement> methods2 = interfaceElement.methods;
|
| - for (MethodElement method in methods2) {
|
| + List<MethodElement> methods3 = interfaceElement.methods;
|
| + for (MethodElement method in methods3) {
|
| if (method.isAccessibleIn(_library) && !method.isStatic()) {
|
| String key = method.name;
|
| if (!unionMap.containsKey(key)) {
|
| @@ -3579,8 +3631,8 @@ class InheritanceManager {
|
| }
|
| }
|
| }
|
| - List<PropertyAccessorElement> accessors2 = interfaceElement.accessors;
|
| - for (PropertyAccessorElement accessor in accessors2) {
|
| + List<PropertyAccessorElement> accessors3 = interfaceElement.accessors;
|
| + for (PropertyAccessorElement accessor in accessors3) {
|
| if (accessor.isAccessibleIn(_library) && !accessor.isStatic()) {
|
| String key = accessor.name;
|
| if (!unionMap.containsKey(key)) {
|
| @@ -3623,7 +3675,7 @@ class InheritanceManager {
|
| for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
|
| executableElementTypes[i] = elements[i].type;
|
| }
|
| - bool foundSubtypeOfAllTypes = true;
|
| + bool foundSubtypeOfAllTypes = false;
|
| for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
|
| FunctionType subtype = executableElementTypes[i];
|
| if (subtype == null) {
|
| @@ -3634,12 +3686,12 @@ class InheritanceManager {
|
| if (i != j) {
|
| if (!subtype.isSubtypeOf(executableElementTypes[j])) {
|
| subtypeOfAllTypes = false;
|
| - foundSubtypeOfAllTypes = false;
|
| break;
|
| }
|
| }
|
| }
|
| if (subtypeOfAllTypes) {
|
| + foundSubtypeOfAllTypes = true;
|
| resultMap[key] = elements[i];
|
| break;
|
| }
|
| @@ -7969,9 +8021,13 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| if (typeNameSimple.name == "boolean") {
|
| reportError(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []);
|
| } else if (isTypeNameInCatchClause(node)) {
|
| - reportError(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, node, [node]);
|
| + reportError(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
|
| + } else if (isTypeNameInAsExpression(node)) {
|
| + reportError(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
|
| + } else if (isTypeNameInIsExpression(node)) {
|
| + reportError(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
|
| } else {
|
| - reportError(StaticWarningCode.UNDEFINED_CLASS, typeNameSimple, [typeNameSimple.name]);
|
| + reportError(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]);
|
| }
|
| elementValid = false;
|
| }
|
| @@ -8001,7 +8057,11 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| }
|
| } else {
|
| if (isTypeNameInCatchClause(node)) {
|
| - reportError(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, node, [node]);
|
| + reportError(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [typeName.name]);
|
| + } else if (isTypeNameInAsExpression(node)) {
|
| + reportError(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
|
| + } else if (isTypeNameInIsExpression(node)) {
|
| + reportError(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.name]);
|
| }
|
| setElement(typeName, _dynamicType.element);
|
| typeName.staticType = _dynamicType;
|
| @@ -8201,9 +8261,23 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| }
|
|
|
| /**
|
| - * Checks if the given type name is used as the exception type in the catch clause.
|
| + * Checks if the given type name is used as the type in an as expression.
|
| + * @param typeName the type name to analyzer
|
| + * @return {@code true} if the given type name is used as the type in an as expression
|
| + */
|
| + bool isTypeNameInAsExpression(TypeName typeName) {
|
| + ASTNode parent2 = typeName.parent;
|
| + if (parent2 is AsExpression) {
|
| + AsExpression asExpression = parent2 as AsExpression;
|
| + return identical(asExpression.type, typeName);
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + /**
|
| + * Checks if the given type name is used as the exception type in a catch clause.
|
| * @param typeName the type name to analyzer
|
| - * @return {@code true} if the given type name is used as the exception type in the catch clause.
|
| + * @return {@code true} if the given type name is used as the exception type in a catch clause
|
| */
|
| bool isTypeNameInCatchClause(TypeName typeName) {
|
| ASTNode parent2 = typeName.parent;
|
| @@ -8215,9 +8289,9 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| }
|
|
|
| /**
|
| - * Checks if the given type name is used as the type in the instance creation expression.
|
| + * Checks if the given type name is used as the type in an instance creation expression.
|
| * @param typeName the type name to analyzer
|
| - * @return {@code true} if the given type name is used as the type in the instance creation
|
| + * @return {@code true} if the given type name is used as the type in an instance creation
|
| * expression
|
| */
|
| bool isTypeNameInInstanceCreationExpression(TypeName typeName) {
|
| @@ -8230,6 +8304,20 @@ class TypeResolverVisitor extends ScopedVisitor {
|
| }
|
|
|
| /**
|
| + * Checks if the given type name is used as the type in an is expression.
|
| + * @param typeName the type name to analyzer
|
| + * @return {@code true} if the given type name is used as the type in an is expression
|
| + */
|
| + bool isTypeNameInIsExpression(TypeName typeName) {
|
| + ASTNode parent2 = typeName.parent;
|
| + if (parent2 is IsExpression) {
|
| + IsExpression isExpression = parent2 as IsExpression;
|
| + return identical(isExpression.type, typeName);
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + /**
|
| * Record that the static type of the given node is the given type.
|
| * @param expression the node whose type is to be recorded
|
| * @param type the static type of the node
|
| @@ -9798,6 +9886,15 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| checkForExportInternalLibrary(node);
|
| return super.visitExportDirective(node);
|
| }
|
| + Object visitFieldDeclaration(FieldDeclaration node) {
|
| + if (!node.isStatic()) {
|
| + VariableDeclarationList variables = node.fields;
|
| + if (variables.isConst()) {
|
| + _errorReporter.reportError4(CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword, []);
|
| + }
|
| + }
|
| + return super.visitFieldDeclaration(node);
|
| + }
|
| Object visitFieldFormalParameter(FieldFormalParameter node) {
|
| checkForConstFormalParameter(node);
|
| checkForFieldInitializingFormalRedirectingConstructor(node);
|
| @@ -11200,7 +11297,7 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| NodeList<VariableDeclaration> variables2 = node.variables;
|
| for (VariableDeclaration variable in variables2) {
|
| if (variable.initializer == null) {
|
| - _errorReporter.reportError2(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, variable, [variable.name.name]);
|
| + _errorReporter.reportError2(StaticWarningCode.FINAL_NOT_INITIALIZED, variable, [variable.name.name]);
|
| foundError = true;
|
| }
|
| }
|
| @@ -11728,16 +11825,25 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| return false;
|
| }
|
| List<ExecutableElement> missingOverridesArray = new List.from(missingOverrides);
|
| + List<String> stringTypeArray = new List<String>(Math.min(missingOverridesSize, 4));
|
| + String GET = "get ";
|
| + String SET = "set ";
|
| + for (int i = 0; i < stringTypeArray.length; i++) {
|
| + stringTypeArray[i] = StringUtilities.EMPTY;
|
| + if (missingOverridesArray[i] is PropertyAccessorElement) {
|
| + stringTypeArray[i] = ((missingOverridesArray[i] as PropertyAccessorElement)).isGetter() ? GET : SET;
|
| + }
|
| + }
|
| if (missingOverridesSize == 1) {
|
| - _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, node.name, [missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName]);
|
| + _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, node.name, [stringTypeArray[0], missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName]);
|
| } else if (missingOverridesSize == 2) {
|
| - _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, node.name, [missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName, missingOverridesArray[1].enclosingElement.displayName, missingOverridesArray[1].displayName]);
|
| + _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, node.name, [stringTypeArray[0], missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName, stringTypeArray[1], missingOverridesArray[1].enclosingElement.displayName, missingOverridesArray[1].displayName]);
|
| } else if (missingOverridesSize == 3) {
|
| - _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, node.name, [missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName, missingOverridesArray[1].enclosingElement.displayName, missingOverridesArray[1].displayName, missingOverridesArray[2].enclosingElement.displayName, missingOverridesArray[2].displayName]);
|
| + _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, node.name, [stringTypeArray[0], missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName, stringTypeArray[1], missingOverridesArray[1].enclosingElement.displayName, missingOverridesArray[1].displayName, stringTypeArray[2], missingOverridesArray[2].enclosingElement.displayName, missingOverridesArray[2].displayName]);
|
| } else if (missingOverridesSize == 4) {
|
| - _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, node.name, [missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName, missingOverridesArray[1].enclosingElement.displayName, missingOverridesArray[1].displayName, missingOverridesArray[2].enclosingElement.displayName, missingOverridesArray[2].displayName, missingOverridesArray[3].enclosingElement.displayName, missingOverridesArray[3].displayName]);
|
| + _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, node.name, [stringTypeArray[0], missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName, stringTypeArray[1], missingOverridesArray[1].enclosingElement.displayName, missingOverridesArray[1].displayName, stringTypeArray[2], missingOverridesArray[2].enclosingElement.displayName, missingOverridesArray[2].displayName, stringTypeArray[3], missingOverridesArray[3].enclosingElement.displayName, missingOverridesArray[3].displayName]);
|
| } else {
|
| - _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, node.name, [missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName, missingOverridesArray[1].enclosingElement.displayName, missingOverridesArray[1].displayName, missingOverridesArray[2].enclosingElement.displayName, missingOverridesArray[2].displayName, missingOverridesArray[3].enclosingElement.displayName, missingOverridesArray[3].displayName, missingOverridesArray.length - 4]);
|
| + _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, node.name, [stringTypeArray[0], missingOverridesArray[0].enclosingElement.displayName, missingOverridesArray[0].displayName, stringTypeArray[1], missingOverridesArray[1].enclosingElement.displayName, missingOverridesArray[1].displayName, stringTypeArray[2], missingOverridesArray[2].enclosingElement.displayName, missingOverridesArray[2].displayName, stringTypeArray[3], missingOverridesArray[3].enclosingElement.displayName, missingOverridesArray[3].displayName, missingOverridesArray.length - 4]);
|
| }
|
| return true;
|
| }
|
| @@ -12245,8 +12351,9 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| }
|
|
|
| /**
|
| - * This checks that if the passed generative constructor has no explicit super constructor
|
| - * invocation, then super class has the default generative constructor.
|
| + * This checks that if the passed generative constructor has neither an explicit super constructor
|
| + * invocation nor a redirecting constructor invocation, that the superclass has a default
|
| + * generative constructor.
|
| * @param node the constructor declaration to evaluate
|
| * @return {@code true} if and only if an error code is generated on the passed node
|
| * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT
|
| @@ -12256,6 +12363,11 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| if (node.factoryKeyword != null) {
|
| return false;
|
| }
|
| + for (ConstructorInitializer constructorInitializer in node.initializers) {
|
| + if (constructorInitializer is SuperConstructorInvocation || constructorInitializer is RedirectingConstructorInvocation) {
|
| + return false;
|
| + }
|
| + }
|
| if (_enclosingClass == null) {
|
| return false;
|
| }
|
| @@ -12264,11 +12376,6 @@ class ErrorVerifier extends RecursiveASTVisitor<Object> {
|
| return false;
|
| }
|
| ClassElement superElement = superType.element;
|
| - for (ConstructorInitializer constructorInitializer in node.initializers) {
|
| - if (constructorInitializer is SuperConstructorInvocation) {
|
| - return false;
|
| - }
|
| - }
|
| ConstructorElement superDefaultConstructor = superElement.unnamedConstructor;
|
| if (superDefaultConstructor != null) {
|
| if (superDefaultConstructor.isFactory()) {
|
| @@ -12485,6 +12592,7 @@ class INIT_STATE implements Comparable<INIT_STATE> {
|
| INIT_STATE(this.name, this.ordinal) {
|
| }
|
| int compareTo(INIT_STATE other) => ordinal - other.ordinal;
|
| + int get hashCode => ordinal;
|
| String toString() => name;
|
| }
|
| /**
|
| @@ -12621,5 +12729,6 @@ class ResolverErrorCode implements Comparable<ResolverErrorCode>, ErrorCode {
|
| String get message => _message;
|
| ErrorType get type => _type;
|
| int compareTo(ResolverErrorCode other) => ordinal - other.ordinal;
|
| + int get hashCode => ordinal;
|
| String toString() => name;
|
| }
|
|
|