/* * Copyright (c) 2012, 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.type; import com.google.dart.engine.element.ClassElement; import com.google.dart.engine.element.ConstructorElement; import com.google.dart.engine.element.LibraryElement; import com.google.dart.engine.element.MethodElement; import com.google.dart.engine.element.PropertyAccessorElement; /** * The interface {@code InterfaceType} defines the behavior common to objects representing the type * introduced by either a class or an interface, or a reference to such a type. * * @coverage dart.engine.type */ public interface InterfaceType extends ParameterizedType { /** * An empty array of types. */ InterfaceType[] EMPTY_ARRAY = new InterfaceType[0]; /** * Return an array containing all of the accessors (getters and setters) declared in this type. * * @return the accessors declared in this type */ public PropertyAccessorElement[] getAccessors(); @Override public ClassElement getElement(); /** * Return the element representing the getter with the given name that is declared in this class, * or {@code null} if this class does not declare a getter with the given name. * * @param getterName the name of the getter to be returned * @return the getter declared in this class with the given name */ public PropertyAccessorElement getGetter(String getterName); /** * Return an array containing all of the interfaces that are implemented by this interface. Note * that this is <b>not</b>, in general, equivalent to getting the interfaces from this type's * element because the types returned by this method will have had their type parameters replaced. * * @return the interfaces that are implemented by this type */ public InterfaceType[] getInterfaces(); /** * Return the least upper bound of this type and the given type, or {@code null} if there is no * least upper bound. * <p> * Given two interfaces <i>I</i> and <i>J</i>, let <i>S<sub>I</sub></i> be the set of * superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of superinterfaces of <i>J</i> * and let <i>S = (I ∪ S<sub>I</sub>) ∩ (J ∪ S<sub>J</sub>)</i>. Furthermore, we * define <i>S<sub>n</sub> = {T | T ∈ S ∧ depth(T) = n}</i> for any finite <i>n</i>, * where <i>depth(T)</i> is the number of steps in the longest inheritance path from <i>T</i> to * <i>Object</i>. Let <i>q</i> be the largest number such that <i>S<sub>q</sub></i> has * cardinality one. The least upper bound of <i>I</i> and <i>J</i> is the sole element of * <i>S<sub>q</sub></i>. * * @param type the other type used to compute the least upper bound * @return the least upper bound of this type and the given type */ @Override public Type getLeastUpperBound(Type type); /** * Return the element representing the method with the given name that is declared in this class, * or {@code null} if this class does not declare a method with the given name. * * @param methodName the name of the method to be returned * @return the method declared in this class with the given name */ public MethodElement getMethod(String methodName); /** * Return an array containing all of the methods declared in this type. * * @return the methods declared in this type */ public MethodElement[] getMethods(); /** * Return an array containing all of the mixins that are applied to the class being extended in * order to derive the superclass of this class. Note that this is <b>not</b>, in general, * equivalent to getting the mixins from this type's element because the types returned by this * method will have had their type parameters replaced. * * @return the mixins that are applied to derive the superclass of this class */ public InterfaceType[] getMixins(); /** * Return the element representing the setter with the given name that is declared in this class, * or {@code null} if this class does not declare a setter with the given name. * * @param setterName the name of the setter to be returned * @return the setter declared in this class with the given name */ public PropertyAccessorElement getSetter(String setterName); /** * Return the type representing the superclass of this type, or null if this type represents the * class 'Object'. Note that this is <b>not</b>, in general, equivalent to getting the superclass * from this type's element because the type returned by this method will have had it's type * parameters replaced. * * @return the superclass of this type */ public InterfaceType getSuperclass(); /** * Return {@code true} if this type is a direct supertype of the given type. The implicit * interface of class <i>I</i> is a direct supertype of the implicit interface of class <i>J</i> * iff: * <ul> * <li><i>I</i> is Object, and <i>J</i> has no extends clause.</li> * <li><i>I</i> is listed in the extends clause of <i>J</i>.</li> * <li><i>I</i> is listed in the implements clause of <i>J</i>.</li> * <li><i>I</i> is listed in the with clause of <i>J</i>.</li> * <li><i>J</i> is a mixin application of the mixin of <i>I</i>.</li> * </ul> * * @param type the type being compared with this type * @return {@code true} if this type is a direct supertype of the given type */ public boolean isDirectSupertypeOf(InterfaceType type); /** * Return {@code true} if this type is more specific than the given type. An interface type * <i>T</i> is more specific than an interface type <i>S</i>, written <i>T « S</i>, if one * of the following conditions is met: * <ul> * <li>Reflexivity: <i>T</i> is <i>S</i>. * <li><i>T</i> is bottom. * <li><i>S</i> is dynamic. * <li>Direct supertype: <i>S</i> is a direct supertype of <i>T</i>. * <li><i>T</i> is a type parameter and <i>S</i> is the upper bound of <i>T</i>. * <li>Covariance: <i>T</i> is of the form <i>I<T<sub>1</sub>, …, T<sub>n</sub>></i> * and S</i> is of the form <i>I<S<sub>1</sub>, …, S<sub>n</sub>></i> and * <i>T<sub>i</sub> « S<sub>i</sub></i>, <i>1 <= i <= n</i>. * <li>Transitivity: <i>T « U</i> and <i>U « S</i>. * </ul> * * @param type the type being compared with this type * @return {@code true} if this type is more specific than the given type */ @Override public boolean isMoreSpecificThan(Type type); /** * Return {@code true} if this type is a subtype of the given type. An interface type <i>T</i> is * a subtype of an interface type <i>S</i>, written <i>T</i> <: <i>S</i>, iff * <i>[bottom/dynamic]T</i> « <i>S</i> (<i>T</i> is more specific than <i>S</i>). If an * interface type <i>I</i> includes a method named <i>call()</i>, and the type of <i>call()</i> is * the function type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>. * * @param type the type being compared with this type * @return {@code true} if this type is a subtype of the given type */ @Override public boolean isSubtypeOf(Type type); /** * Return the element representing the constructor that results from looking up the given * constructor in this class with respect to the given library, or {@code null} if the look up * fails. The behavior of this method is defined by the Dart Language Specification in section * 12.11.1: <blockquote>If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be * the constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T<i>. Otherwise, if * <i>q</i> is not defined or not accessible, a NoSuchMethodException is thrown. </blockquote> * * @param constructorName the name of the constructor being looked up * @param library the library with respect to which the lookup is being performed * @return the result of looking up the given constructor in this class with respect to the given * library */ public ConstructorElement lookUpConstructor(String constructorName, LibraryElement library); /** * Return the element representing the getter that results from looking up the given getter in * this class with respect to the given library, or {@code null} if the look up fails. The * behavior of this method is defined by the Dart Language Specification in section 12.15.1: * <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i> * with respect to library <i>L</i> is: * <ul> * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup. * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>. * Otherwise, we say that the lookup has failed.</li> * </ul> * </blockquote> * * @param getterName the name of the getter being looked up * @param library the library with respect to which the lookup is being performed * @return the result of looking up the given getter in this class with respect to the given * library */ public PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library); /** * Return the element representing the getter that results from looking up the given getter in the * superclass of this class with respect to the given library, or {@code null} if the look up * fails. The behavior of this method is defined by the Dart Language Specification in section * 12.15.1: <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class * <i>C</i> with respect to library <i>L</i> is: * <ul> * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup. * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>. * Otherwise, we say that the lookup has failed.</li> * </ul> * </blockquote> * * @param getterName the name of the getter being looked up * @param library the library with respect to which the lookup is being performed * @return the result of looking up the given getter in this class with respect to the given * library */ public PropertyAccessorElement lookUpGetterInSuperclass(String getterName, LibraryElement library); /** * Return the element representing the method that results from looking up the given method in * this class with respect to the given library, or {@code null} if the look up fails. The * behavior of this method is defined by the Dart Language Specification in section 12.15.1: * <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect to library * <i>L</i> is: * <ul> * <li>If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect * to <i>L</i>. Otherwise, we say that the lookup has failed.</li> * </ul> * </blockquote> * * @param methodName the name of the method being looked up * @param library the library with respect to which the lookup is being performed * @return the result of looking up the given method in this class with respect to the given * library */ public MethodElement lookUpMethod(String methodName, LibraryElement library); /** * Return the element representing the method that results from looking up the given method in the * superclass of this class with respect to the given library, or {@code null} if the look up * fails. The behavior of this method is defined by the Dart Language Specification in section * 12.15.1: <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect * to library <i>L</i> is: * <ul> * <li>If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect * to <i>L</i>. Otherwise, we say that the lookup has failed.</li> * </ul> * </blockquote> * * @param methodName the name of the method being looked up * @param library the library with respect to which the lookup is being performed * @return the result of looking up the given method in this class with respect to the given * library */ public MethodElement lookUpMethodInSuperclass(String methodName, LibraryElement library); /** * Return the element representing the setter that results from looking up the given setter in * this class with respect to the given library, or {@code null} if the look up fails. The * behavior of this method is defined by the Dart Language Specification in section 12.16: * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i> * with respect to library <i>L</i> is: * <ul> * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup. * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>. * Otherwise, we say that the lookup has failed.</li> * </ul> * </blockquote> * * @param setterName the name of the setter being looked up * @param library the library with respect to which the lookup is being performed * @return the result of looking up the given setter in this class with respect to the given * library */ public PropertyAccessorElement lookUpSetter(String setterName, LibraryElement library); /** * Return the element representing the setter that results from looking up the given setter in the * superclass of this class with respect to the given library, or {@code null} if the look up * fails. The behavior of this method is defined by the Dart Language Specification in section * 12.16: <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class * <i>C</i> with respect to library <i>L</i> is: * <ul> * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup. * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>. * Otherwise, we say that the lookup has failed.</li> * </ul> * </blockquote> * * @param setterName the name of the setter being looked up * @param library the library with respect to which the lookup is being performed * @return the result of looking up the given setter in this class with respect to the given * library */ public PropertyAccessorElement lookUpSetterInSuperclass(String setterName, LibraryElement library); /** * Return the type resulting from substituting the given arguments for this type's parameters. * This is fully equivalent to {@code substitute(argumentTypes, getTypeArguments())}. * * @param argumentTypes the actual type arguments being substituted for the type parameters * @return the result of performing the substitution */ public InterfaceType substitute(Type[] argumentTypes); @Override public InterfaceType substitute(Type[] argumentTypes, Type[] parameterTypes); }