001package de.monochromata.anaphors.ast.relatedexp;
002
003import java.util.List;
004import java.util.function.Function;
005
006import de.monochromata.anaphors.ast.relatedexp.strategy.RelatedExpressionStrategy;
007
008/**
009 * Represents the function of an expression, or statement as related expression.
010 *
011 * @param <N>  The node type in the AST
012 * @param <T>  The type type
013 * @param <B>  The binding type
014 * @param <TB> The type binding type
015 * @param <S>  The scope type (optional)
016 * @param <QI> The type used to represent qualified identifiers
017 * @param <R>  The sub-type of related expression to use
018 */
019public interface RelatedExpression<N, T, B, TB extends B, S, QI, R extends RelatedExpression<N, T, B, TB, S, QI, R>> {
020
021    /**
022     * If the related expression is effectively final, its value is identical at
023     * run-time, regardless of whether the related expression occurs in its original
024     * position, or would be moved or copied to the position of the anaphor.
025     *
026     * @return {@literal true}, if the related expression is effectively final.
027     */
028    public boolean isEffectivelyFinal();
029
030    /**
031     * @return {@literal true}, if anaphor resolution should replace the related
032     *         expression with a declaration of a temporary local variable. This is
033     *         required whenever the related expression is not effectively final and
034     *         is not already used to initialize an effectively final local variable
035     *         that can be re-used.
036     * @see #isEffectivelyFinal()
037     */
038    default boolean shouldResolutionReplaceRelatedExpressionWithTempDeclaration() {
039        return !isEffectivelyFinal();
040    }
041
042    public N getRelatedExpression();
043
044    /**
045     * Replaces the current related expression with the given one.
046     *
047     * @param relatedExpression The new related expression
048     * @see #getRelatedExpression()
049     * @see #getStrategy()
050     * @deprecated
051     */
052    @Deprecated
053    public void setRelatedExpression(N relatedExpression);
054
055    public RelatedExpressionStrategy<N, T, B, TB, S, QI, R> getStrategy();
056
057    /**
058     * Used to resolve referential ambiguity between related expressions.
059     *
060     * @param other Another related expression.
061     * @return True, if this related expression refers to the same referent as
062     *         <code>other</code> and this related expression should be used instead
063     *         of <code>other</code> in order to eliminate the ambiguity between the
064     *         two. False is returned otherwise.
065     */
066    public boolean canBeUsedInsteadOf(R other);
067
068    /**
069     * Whether or not this related expression declares a name.
070     *
071     * @return True, if a name is declared, false otherwise.
072     */
073    default boolean hasName() {
074        return null != getName();
075    }
076
077    /**
078     * Return the name used as identifier in the related expression, if the related
079     * expression declares a name. Null is returned, if {@link #hasName()} returns
080     * false.
081     *
082     * @see #hasName()
083     * @return Null, if {@link #hasName()} returns false.
084     */
085    public QI getName();
086
087    public List<QI> getPartNames();
088
089    public List<QI> getAssociateNames();
090
091    public List<QI> getContainedNamesFromSurface();
092
093    /**
094     * Resolves the binding of the name declared in the related expression. Returns
095     * {@literal null}, if {@link #hasName()} returns {@literal false}.
096     *
097     * @param scope The scope containing the related expression if used by the
098     *              compiler-specific implementation. Implementations of this method
099     *              must not access the scope but merely pass it on to SPI's they
100     *              invoke.
101     * @return The resolved binding.
102     */
103    public B resolveNameBinding(S scope);
104
105    public int getLengthOfTypeForTempVar(S scope);
106
107    /**
108     * Returns the type of the related expression for use in declaring a local
109     * temporary variable. This method needs to add import declarations if necessary
110     * to make the type useable for the temp var.
111     *
112     * @param importRewrite To turn a type binding into a type that can be used in
113     *                      the AST
114     */
115    @Deprecated
116    public T getTypeForTempVar(S scope, Function<TB, T> importRewrite);
117
118    /**
119     * Resolve the type of the related expression
120     *
121     * @param scope The scope containing the related expression if used by the
122     *              compiler-specific implementation. Implementations of this method
123     *              must not access the scope but merely pass it on to SPI's they
124     *              invoke.
125     * @return The resolved type.
126     */
127    public TB resolveType(S scope);
128
129    public List<TB> resolvePartTypes(S scope);
130
131    public List<TB> resolveAssociateTypes(S scope);
132
133    public List<TB> resolveContainedTypesFromSurface(S scope);
134
135    public String getDescription();
136
137    public int getLine();
138
139    public int getColumn();
140
141}