/* * 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.element; import com.google.dart.engine.ast.AstNode; import com.google.dart.engine.ast.CompilationUnit; import com.google.dart.engine.context.AnalysisContext; import com.google.dart.engine.context.AnalysisException; import com.google.dart.engine.source.Source; import java.util.Comparator; /** * The interface {@code Element} defines the behavior common to all of the elements in the element * model. Generally speaking, the element model is a semantic model of the program that represents * things that are declared with a name and hence can be referenced elsewhere in the code. * <p> * There are two exceptions to the general case. First, there are elements in the element model that * are created for the convenience of various kinds of analysis but that do not have any * corresponding declaration within the source code. Such elements are marked as being * <i>synthetic</i>. Examples of synthetic elements include * <ul> * <li>default constructors in classes that do not define any explicit constructors, * <li>getters and setters that are induced by explicit field declarations, * <li>fields that are induced by explicit declarations of getters and setters, and * <li>functions representing the initialization expression for a variable. * </ul> * <p> * Second, there are elements in the element model that do not have a name. These correspond to * unnamed functions and exist in order to more accurately represent the semantic structure of the * program. * * @coverage dart.engine.element */ public interface Element { /** * An Unicode right arrow. */ public static final String RIGHT_ARROW = " \u2192 "; //$NON-NLS-1$ /** * A comparator that can be used to sort elements by their name offset. Elements with a smaller * offset will be sorted to be before elements with a larger name offset. */ public static final Comparator<Element> SORT_BY_OFFSET = new Comparator<Element>() { @Override public int compare(Element firstElement, Element secondElement) { return firstElement.getNameOffset() - secondElement.getNameOffset(); } }; /** * Use the given visitor to visit this element. * * @param visitor the visitor that will visit this element * @return the value returned by the visitor as a result of visiting this element */ public <R> R accept(ElementVisitor<R> visitor); /** * Return the documentation comment for this element as it appears in the original source * (complete with the beginning and ending delimiters), or {@code null} if this element does not * have a documentation comment associated with it. This can be a long-running operation if the * information needed to access the comment is not cached. * * @return this element's documentation comment * @throws AnalysisException if the documentation comment could not be determined because the * analysis could not be performed */ public String computeDocumentationComment() throws AnalysisException; /** * Return the element of the given class that most immediately encloses this element, or * {@code null} if there is no enclosing element of the given class. * * @param elementClass the class of the element to be returned * @return the element that encloses this element */ public <E extends Element> E getAncestor(Class<E> elementClass); /** * Return the analysis context in which this element is defined. * * @return the analysis context in which this element is defined */ public AnalysisContext getContext(); /** * Return the display name of this element, or {@code null} if this element does not have a name. * <p> * In most cases the name and the display name are the same. Differences though are cases such as * setters where the name of some setter {@code set f(x)} is {@code f=}, instead of {@code f}. * * @return the display name of this element */ public String getDisplayName(); /** * Return the element that either physically or logically encloses this element. This will be * {@code null} if this element is a library because libraries are the top-level elements in the * model. * * @return the element that encloses this element */ public Element getEnclosingElement(); /** * Return a display name for the given element that includes the path to the compilation unit in * which the type is defined. * * @param shortName the short display name. If null, {@link getDisplayName()} is used. * @return a display name that can help distinguish between two types with the same name */ public String getExtendedDisplayName(String shortName); /** * Return the kind of element that this is. * * @return the kind of this element */ public ElementKind getKind(); /** * Return the library that contains this element. This will be the element itself if it is a * library element. This will be {@code null} if this element is an HTML file because HTML files * are not contained in libraries. * * @return the library that contains this element */ public LibraryElement getLibrary(); /** * Return an object representing the location of this element in the element model. The object can * be used to locate this element at a later time. * * @return the location of this element in the element model */ public ElementLocation getLocation(); /** * Return an array containing all of the metadata associated with this element. The array will be * empty if the element does not have any metadata or if the library containing this element has * not yet been resolved. * * @return the metadata associated with this element */ public ElementAnnotation[] getMetadata(); /** * Return the name of this element, or {@code null} if this element does not have a name. * * @return the name of this element */ public String getName(); /** * Return the offset of the name of this element in the file that contains the declaration of this * element, or {@code -1} if this element is synthetic, does not have a name, or otherwise does * not have an offset. * * @return the offset of the name of this element */ public int getNameOffset(); /** * Return the resolved {@link AstNode} node that declares this {@link Element}. * <p> * This method is expensive, because resolved AST might be evicted from cache, so parsing and * resolving will be performed. * <p> * <b>Note:</b> This method cannot be used in an async environment. * * @return the resolved {@link AstNode}, maybe {@code null} if {@link Element} is synthetic or * isn't contained in a compilation unit, such as a {@link LibraryElement}. */ public AstNode getNode() throws AnalysisException; /** * Return the source that contains this element, or {@code null} if this element is not contained * in a source. * * @return the source that contains this element */ public Source getSource(); /** * Return the resolved {@link CompilationUnit} that declares this {@link Element}. * <p> * This method is expensive, because resolved AST might have been already evicted from cache, so * parsing and resolving will be performed. * * @return the resolved {@link CompilationUnit}, maybe {@code null} if synthetic {@link Element}. */ public CompilationUnit getUnit() throws AnalysisException; /** * Return {@code true} if this element, assuming that it is within scope, is accessible to code in * the given library. This is defined by the Dart Language Specification in section 3.2: * <blockquote> A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is declared * in <i>L</i> or if <i>m</i> is public. </blockquote> * * @param library the library in which a possible reference to this element would occur * @return {@code true} if this element is accessible to code in the given library */ public boolean isAccessibleIn(LibraryElement library); /** * Return {@code true} if this element has an annotation of the form '@deprecated' or * '@Deprecated('..')'. * * @return {@code true} if this element is deprecated */ public boolean isDeprecated(); /** * Return {@code true} if this element has an annotation of the form '@override'. * * @return {@code true} if this element is overridden */ public boolean isOverride(); /** * Return {@code true} if this element is private. Private elements are visible only within the * library in which they are declared. * * @return {@code true} if this element is private */ public boolean isPrivate(); /** * Return {@code true} if this element is public. Public elements are visible within any library * that imports the library in which they are declared. * * @return {@code true} if this element is public */ public boolean isPublic(); /** * Return {@code true} if this element is synthetic. A synthetic element is an element that is not * represented in the source code explicitly, but is implied by the source code, such as the * default constructor for a class that does not explicitly define any constructors. * * @return {@code true} if this element is synthetic */ public boolean isSynthetic(); /** * Use the given visitor to visit all of the children of this element. There is no guarantee of * the order in which the children will be visited. * * @param visitor the visitor that will be used to visit the children of this element */ public void visitChildren(ElementVisitor<?> visitor); }