001package de.monochromata.anaphors.ast.reference;
002
003import de.monochromata.anaphors.ast.feature.FeatureContainer;
004import de.monochromata.anaphors.ast.spi.RelatedExpressionsSpi;
005import de.monochromata.anaphors.ast.strategy.AnaphorResolutionStrategy;
006
007/**
008 * The representation of a referent. A referent may provide a number of
009 * features.
010 *
011 * @param <TB>
012 *            The type binding type
013 * @param <S>
014 *            The scope type (optional)
015 * @param <I>
016 *            The type used to represent identifiers
017 * @param <QI>
018 *            The type used to represent qualified identifiers
019 */
020public interface Referent<TB, S, I, QI> extends FeatureContainer<QI> {
021
022    /**
023     * Used to resolve ambiguity between referents. Cases of resolvable ambiguity
024     * include e.g. a referent that represents the invocation of a getter method
025     * that returns the value of the field that is represented by another referent.
026     *
027     * @param other
028     *            Another referent.
029     * @return True, if this referent represents the same referent as {@code other}
030     *         and this related expression should be used instead of {@code other}
031     *         in order to eliminate the ambiguity between the two. False is
032     *         returned otherwise.
033     */
034    public boolean canBeUsedInsteadOf(Referent<TB, S, I, QI> other);
035
036    public boolean hasName();
037
038    /**
039     * Returns the name of this referent.
040     *
041     * If {@link #hasMethodName()} returns true and the method name is the only name
042     * of this referent, this method returns a name constructed from the method
043     * name. That name is constructed by removing any getter or setter prefix to the
044     * method name and by turning the first character of the remaining string into
045     * lower case.
046     *
047     * @return The name of this referent.
048     * @throws UnsupportedOperationException
049     *             If {@link #hasName()} returns false.
050     */
051    public QI getName();
052
053    /**
054     * Returns true, if this referent is created by a method invocation.
055     *
056     * TODO: Maybe replace by a system of thematic roles
057     *
058     * @return True, if the referent is created by a method invocation, false
059     *         otherwise.
060     * @see #getMethodName()
061     */
062    public boolean hasMethodName();
063
064    /**
065     * Returns the name of the method invocation which creates this referent, if
066     * {@link #hasMethodName()} returns true.
067     *
068     * TODO: Maybe replace by a system of thematic roles
069     *
070     * @return The method name.
071     * @throws UnsupportedOperationException
072     *             If {@link #hasMethodName()} returns false.
073     */
074    public I getMethodName();
075
076    /**
077     * The type of the referent - is identical to the return type, if the referent
078     * is a method.
079     *
080     * @param scope
081     *            The scope containing the referent if used by the compiler-specific
082     *            implementation. Implementations of this method must not access the
083     *            scope but merely pass it on to SPI's they invoke.
084     * @return The type binding of the referent.
085     */
086    public TB resolveType(S scope);
087
088    /**
089     * Return an object whose {@link Object#toString()} method returns a
090     * representation of the internal state of the referent that can be passed to
091     * {@link AnaphorResolutionStrategy#createReferent(Object, de.monochromata.anaphors.ast.relatedexp.RelatedExpression, Object)}
092     *
093     * TODO: Use {@link RelatedExpressionsSpi} methods to convert the memento to a
094     * String and back, or create a ReferentSpi.
095     *
096     * @return A memento object.
097     */
098    public Object getMemento();
099
100    public String getDescription();
101}