/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.engine.error; /** * The enumeration {@code StaticTypeWarningCode} defines the error codes used for static type * warnings. The convention for this class is for the name of the error code to indicate the problem * that caused the error to be generated and for the error message to explain what is wrong and, * when appropriate, how the problem can be corrected. * * @coverage dart.engine.error */ public enum StaticTypeWarningCode implements ErrorCode { /** * 12.7 Lists: A fresh instance (7.6.1) <i>a</i>, of size <i>n</i>, whose class implements the * built-in class <i>List<E></i> is allocated. * * @param numTypeArgument the number of provided type arguments */ EXPECTED_ONE_LIST_TYPE_ARGUMENTS( "List literal requires exactly one type arguments or none, but %d found"), /** * 12.8 Maps: A fresh instance (7.6.1) <i>m</i>, of size <i>n</i>, whose class implements the * built-in class <i>Map<K, V></i> is allocated. * * @param numTypeArgument the number of provided type arguments */ EXPECTED_TWO_MAP_TYPE_ARGUMENTS( "Map literal requires exactly two type arguments or none, but %d found"), /** * 9 Functions: It is a static warning if the declared return type of a function marked async* may * not be assigned to Stream. */ ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE( "Functions marked 'async*' must have a return type assignable to 'Stream'"), /** * 9 Functions: It is a static warning if the declared return type of a function marked async may * not be assigned to Stream. */ ILLEGAL_ASYNC_RETURN_TYPE( "Functions marked 'async' must have a return type assignable to 'Future'"), /** * 9 Functions: It is a static warning if the declared return type of a function marked sync* may * not be assigned to Stream. */ ILLEGAL_SYNC_GENERATOR_RETURN_TYPE( "Functions marked 'sync*' must have a return type assignable to 'Iterable'"), /** * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type * warning if <i>T</i> does not have an accessible instance setter named <i>v=</i>. * * @see #UNDEFINED_SETTER */ // Low priority- This is currently being caught by StaticWarningCode.UNDEFINED_SETTER. In order to // identify situations where the setter is actually inaccessible, we would need to convert the // lookups in the resolver (ElementResolver) to use the InheritanceManager. After this, we would // need to enhance the InheritanceManager to be able to make the distinction. INACCESSIBLE_SETTER(""), /** * 8.1.1 Inheritance and Overriding: However, if the above rules would cause multiple members * <i>m<sub>1</sub>, …, m<sub>k</sub></i> with the same name <i>n</i> that would be * inherited (because identically named members existed in several superinterfaces) then at most * one member is inherited. * <p> * If the static types <i>T<sub>1</sub>, …, T<sub>k</sub></i> of the members * <i>m<sub>1</sub>, …, m<sub>k</sub></i> are not identical, then there must be a member * <i>m<sub>x</sub></i> such that <i>T<sub>x</sub> <: T<sub>i</sub>, 1 <= x <= k</i> for * all <i>i, 1 <= i <= k</i>, or a static type warning occurs. The member that is inherited * is <i>m<sub>x</sub></i>, if it exists; otherwise: * <ul> * <li>Let <i>numberOfPositionals</i>(<i>f</i>) denote the number of positional parameters of a * function <i>f</i>, and let <i>numberOfRequiredParams</i>(<i>f</i>) denote the number of * required parameters of a function <i>f</i>. Furthermore, let <i>s</i> denote the set of all * named parameters of the <i>m<sub>1</sub>, …, m<sub>k</sub></i>. Then let * <ul> * <li><i>h = max(numberOfPositionals(m<sub>i</sub>)),</i></li> * <li><i>r = min(numberOfRequiredParams(m<sub>i</sub>)), for all <i>i</i>, 1 <= i <= k.</i></li> * </ul> * If <i>r <= h</i> then <i>I</i> has a method named <i>n</i>, with <i>r</i> required parameters * of type <b>dynamic</b>, <i>h</i> positional parameters of type <b>dynamic</b>, named parameters * <i>s</i> of type <b>dynamic</b> and return type <b>dynamic</b>.</li> * <li>Otherwise none of the members <i>m<sub>1</sub>, …, m<sub>k</sub></i> is inherited. * </ul> */ INCONSISTENT_METHOD_INHERITANCE( "'%s' is inherited by at least two interfaces inconsistently, from %s"), /** * 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does not have an * accessible (3.2) instance member named <i>m</i>. * * @param memberName the name of the static member * @see UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER */ INSTANCE_ACCESS_TO_STATIC_MEMBER("Static member '%s' cannot be accessed using instance access"), /** * 12.18 Assignment: It is a static type warning if the static type of <i>e</i> may not be * assigned to the static type of <i>v</i>. The static type of the expression <i>v = e</i> is the * static type of <i>e</i>. * <p> * 12.18 Assignment: It is a static type warning if the static type of <i>e</i> may not be * assigned to the static type of <i>C.v</i>. The static type of the expression <i>C.v = e</i> is * the static type of <i>e</i>. * <p> * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to <i>T</i>. * * @param rhsTypeName the name of the right hand side type * @param lhsTypeName the name of the left hand side type */ INVALID_ASSIGNMENT("A value of type '%s' cannot be assigned to a variable of type '%s'"), /** * 12.15.1 Ordinary Invocation: An ordinary method invocation <i>i</i> has the form * <i>o.m(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, … * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. * <p> * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type. If <i>T.m</i> does * not exist, or if <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. * <p> * 12.15.3 Static Invocation: It is a static type warning if the type <i>F</i> of <i>C.m</i> may * not be assigned to a function type. * <p> * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form * <i>super.m(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, … * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. If <i>S.m</i> exists, it is a static warning if the type * <i>F</i> of <i>S.m</i> may not be assigned to a function type. * * @param nonFunctionIdentifier the name of the identifier that is not a function type */ INVOCATION_OF_NON_FUNCTION("'%s' is not a method"), /** * 12.14.4 Function Expression Invocation: A function expression invocation <i>i</i> has the form * <i>e<sub>f</sub>(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, * …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>e<sub>f</sub></i> is an expression. * <p> * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub></i> may not be * assigned to a function type. */ INVOCATION_OF_NON_FUNCTION_EXPRESSION("Cannot invoke a non-function"), /** * 12.20 Conditional: It is a static type warning if the type of <i>e<sub>1</sub></i> may not be * assigned to bool. * <p> * 13.5 If: It is a static type warning if the type of the expression <i>b</i> may not be assigned * to bool. * <p> * 13.7 While: It is a static type warning if the type of <i>e</i> may not be assigned to bool. * <p> * 13.8 Do: It is a static type warning if the type of <i>e</i> cannot be assigned to bool. */ NON_BOOL_CONDITION("Conditions must have a static type of 'bool'"), /** * 13.15 Assert: It is a static type warning if the type of <i>e</i> may not be assigned to either * bool or () → bool */ NON_BOOL_EXPRESSION("Assertions must be on either a 'bool' or '() -> bool'"), /** * 12.28 Unary Expressions: The expression !<i>e</i> is equivalent to the expression * <i>e</i>?<b>false<b> : <b>true</b>. * <p> * 12.20 Conditional: It is a static type warning if the type of <i>e<sub>1</sub></i> may not be * assigned to bool. */ NON_BOOL_NEGATION_EXPRESSION("Negation argument must have a static type of 'bool'"), /** * 12.21 Logical Boolean Expressions: It is a static type warning if the static types of both of * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> may not be assigned to bool. * * @param operator the lexeme of the logical operator */ NON_BOOL_OPERAND("The operands of the '%s' operator must be assignable to 'bool'"), /** * 15.8 Parameterized Types: It is a static type warning if <i>A<sub>i</sub>, 1 <= i <= * n</i> does not denote a type in the enclosing lexical scope. */ NON_TYPE_AS_TYPE_ARGUMENT( "The name '%s' is not a type and cannot be used as a parameterized type"), /** * 13.11 Return: It is a static type warning if the type of <i>e</i> may not be assigned to the * declared return type of the immediately enclosing function. * * @param actualReturnType the return type as declared in the return statement * @param expectedReturnType the expected return type as defined by the method * @param methodName the name of the method */ RETURN_OF_INVALID_TYPE("The return type '%s' is not a '%s', as defined by the method '%s'"), /** * 12.11 Instance Creation: It is a static type warning if any of the type arguments to a * constructor of a generic type <i>G</i> invoked by a new expression or a constant object * expression are not subtypes of the bounds of the corresponding formal type parameters of * <i>G</i>. * <p> * 15.8 Parameterized Types: If <i>S</i> is the static type of a member <i>m</i> of <i>G</i>, then * the static type of the member <i>m</i> of <i>G<A<sub>1</sub>, …, * A<sub>n</sub>></i> is <i>[A<sub>1</sub>, …, A<sub>n</sub>/T<sub>1</sub>, …, * T<sub>n</sub>]S</i> where <i>T<sub>1</sub>, …, T<sub>n</sub></i> are the formal type * parameters of <i>G</i>. Let <i>B<sub>i</sub></i> be the bounds of <i>T<sub>i</sub>, 1 <= i * <= n</i>. It is a static type warning if <i>A<sub>i</sub></i> is not a subtype of * <i>[A<sub>1</sub>, …, A<sub>n</sub>/T<sub>1</sub>, …, * T<sub>n</sub>]B<sub>i</sub>, 1 <= i <= n</i>. * <p> * 7.6.2 Factories: It is a static type warning if any of the type arguments to <i>k'</i> are not * subtypes of the bounds of the corresponding formal type parameters of type. * * @param boundedTypeName the name of the type used in the instance creation that should be * limited by the bound as specified in the class declaration * @param boundingTypeName the name of the bounding type * @see #TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND */ TYPE_ARGUMENT_NOT_MATCHING_BOUNDS("'%s' does not extend '%s'"), /** * 10 Generics: It is a static type warning if a type parameter is a supertype of its upper bound. * * @param typeParameterName the name of the type parameter * @see #TYPE_ARGUMENT_NOT_MATCHING_BOUNDS */ TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND("'%s' cannot be a supertype of its upper bound"), /** * 12.17 Getter Invocation: It is a static warning if there is no class <i>C</i> in the enclosing * lexical scope of <i>i</i>, or if <i>C</i> does not declare, implicitly or explicitly, a getter * named <i>m</i>. * * @param constantName the name of the enumeration constant that is not defined * @param enumName the name of the enumeration used to access the constant */ UNDEFINED_ENUM_CONSTANT("There is no constant named '%s' in '%s'"), /** * 12.15.3 Unqualified Invocation: If there exists a lexically visible declaration named * <i>id</i>, let <i>f<sub>id</sub></i> be the innermost such declaration. Then: [skip]. * Otherwise, <i>f<sub>id</sub></i> is considered equivalent to the ordinary method invocation * <b>this</b>.<i>id</i>(<i>a<sub>1</sub></i>, ..., <i>a<sub>n</sub></i>, <i>x<sub>n+1</sub></i> : * <i>a<sub>n+1</sub></i>, ..., <i>x<sub>n+k</sub></i> : <i>a<sub>n+k</sub></i>). * * @param methodName the name of the method that is undefined */ UNDEFINED_FUNCTION("The function '%s' is not defined"), /** * 12.17 Getter Invocation: Let <i>T</i> be the static type of <i>e</i>. It is a static type * warning if <i>T</i> does not have a getter named <i>m</i>. * * @param getterName the name of the getter * @param enclosingType the name of the enclosing type where the getter is being looked for */ UNDEFINED_GETTER("There is no such getter '%s' in '%s'"), /** * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>. It is a static type * warning if <i>T</i> does not have an accessible instance member named <i>m</i>. * * @param methodName the name of the method that is undefined * @param typeName the resolved type name that the method lookup is happening on */ UNDEFINED_METHOD("The method '%s' is not defined for the class '%s'"), /** * 12.18 Assignment: Evaluation of an assignment of the form * <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] = <i>e<sub>3</sub></i> is equivalent to the * evaluation of the expression (a, i, e){a.[]=(i, e); return e;} (<i>e<sub>1</sub></i>, * <i>e<sub>2</sub></i>, <i>e<sub>2</sub></i>). * <p> * 12.29 Assignable Expressions: An assignable expression of the form * <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] is evaluated as a method invocation of the operator * method [] on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>. * <p> * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>. It is a static type * warning if <i>T</i> does not have an accessible instance member named <i>m</i>. * * @param operator the name of the operator * @param enclosingType the name of the enclosing type where the operator is being looked for */ UNDEFINED_OPERATOR("There is no such operator '%s' in '%s'"), /** * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type * warning if <i>T</i> does not have an accessible instance setter named <i>v=</i>. * * @param setterName the name of the setter * @param enclosingType the name of the enclosing type where the setter is being looked for * @see #INACCESSIBLE_SETTER */ UNDEFINED_SETTER("There is no such setter '%s' in '%s'"), /** * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form * <i>super.m(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, … * x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a static type warning if <i>S</i> does not have an * accessible instance member named <i>m</i>. * * @param methodName the name of the method that is undefined * @param typeName the resolved type name that the method lookup is happening on */ UNDEFINED_SUPER_METHOD("There is no such method '%s' in '%s'"), /** * 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does not have an * accessible (3.2) instance member named <i>m</i>. * <p> * This is a specialization of {@link #INSTANCE_ACCESS_TO_STATIC_MEMBER} that is used when we are * able to find the name defined in a supertype. It exists to provide a more informative error * message. */ UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER( "Static members from supertypes must be qualified by the name of the defining type"), /** * 15.8 Parameterized Types: It is a static type warning if <i>G</i> is not a generic type with * exactly <i>n</i> type parameters. * * @param typeName the name of the type being referenced (<i>G</i>) * @param parameterCount the number of type parameters that were declared * @param argumentCount the number of type arguments provided * @see CompileTimeErrorCode#CONST_WITH_INVALID_TYPE_PARAMETERS * @see CompileTimeErrorCode#NEW_WITH_INVALID_TYPE_PARAMETERS */ WRONG_NUMBER_OF_TYPE_ARGUMENTS( "The type '%s' is declared with %d type parameters, but %d type arguments were given"), /** * 17.16.1 Yield: Let T be the static type of e [the expression to the right of "yield"] and let f * be the immediately enclosing function. It is a static type warning if either: * <ul> * <li>the body of f is marked async* and the type Stream<T> may not be assigned to the * declared return type of f. * <li>the body of f is marked sync* and the type Iterable<T> may not be assigned to the * declared return type of f. * <p> * 17.16.2 Yield-Each: Let T be the static type of e [the expression to the right of "yield*"] and * let f be the immediately enclosing function. It is a static type warning if T may not be * assigned to the declared return type of f. If f is synchronous it is a static type warning if T * may not be assigned to Iterable. If f is asynchronous it is a static type warning if T may not * be assigned to Stream. */ YIELD_OF_INVALID_TYPE( "The type '%s' implied by the 'yield' expression must be assignable to '%s'"); /** * The template used to create the message to be displayed for this error. */ private final String message; /** * The template used to create the correction to be displayed for this error, or {@code null} if * there is no correction information for this error. */ public String correction; /** * Initialize a newly created error code to have the given message. * * @param message the message template used to create the message to be displayed for the error */ private StaticTypeWarningCode(String message) { this(message, null); } /** * Initialize a newly created error code to have the given message and correction. * * @param message the template used to create the message to be displayed for the error * @param correction the template used to create the correction to be displayed for the error */ private StaticTypeWarningCode(String message, String correction) { this.message = message; this.correction = correction; } @Override public String getCorrection() { return correction; } @Override public ErrorSeverity getErrorSeverity() { return ErrorType.STATIC_TYPE_WARNING.getSeverity(); } @Override public String getMessage() { return message; } @Override public ErrorType getType() { return ErrorType.STATIC_TYPE_WARNING; } @Override public String getUniqueName() { return getClass().getSimpleName() + '.' + name(); } }