001package de.monochromata.anaphors.ast.relatedexp; 002 003import java.util.List; 004import java.util.function.BiFunction; 005import java.util.function.BiPredicate; 006import java.util.function.Function; 007import java.util.function.Supplier; 008 009import de.monochromata.anaphors.ast.relatedexp.strategy.RelatedExpressionStrategy; 010import de.monochromata.anaphors.ast.spi.RelatedExpressionsSpi; 011 012/** 013 * An abstract base class for implementing related expressions. 014 * 015 * @param <N> The node type in the AST 016 * @param <T> The type type 017 * @param <B> The binding type 018 * @param <MB> The method binding type 019 * @param <TB> The type binding type 020 * @param <S> The scope type (optional) 021 * @param <QI> The type used to represent qualified identifiers 022 * @param <EV> The type of the event contained in the condition that is 023 * evaluated to check when the perspectivations shall be applied. 024 * @param <PP> The type used for positions that carry perspectivations 025 * @param <R> The sub-type of related expression to use 026 * 027 * @deprecated {@link RelatedExpression} will be turned into a POJO instead 028 */ 029@Deprecated 030public class DefaultRelatedExpression<N, T, B, MB extends B, TB extends B, S, QI, EV, PP, R extends DefaultRelatedExpression<N, T, B, MB, TB, S, QI, EV, PP, R>> 031 implements RelatedExpression<N, T, B, TB, S, QI, R> { 032 033 private final boolean isEffectivelyFinal; 034 private final Supplier<QI> nameSupplier; 035 private N relatedExpression; 036 private final RelatedExpressionStrategy<N, T, B, TB, S, QI, R> strategy; 037 protected final RelatedExpressionsSpi<N, ?, T, B, MB, TB, S, ?, QI, EV, PP, R> relatedExpressionsSpi; 038 private final Function<S, B> nameBindingResolver; 039 private final Function<S, Integer> lengthOfTypeForTempVarFunction; 040 private final BiFunction<S, Function<TB, T>, T> typeForTypeVarFunction; 041 private final Function<S, TB> typeResolver; 042 private final BiPredicate<? super DefaultRelatedExpression<N, T, B, MB, TB, S, QI, EV, PP, R>, R> canBeUsedInsteadOfBiPredicate; 043 044 /** 045 * Used in contract testing. 046 */ 047 @SuppressWarnings("unused") 048 protected DefaultRelatedExpression() { 049 this(false, null, null, null, null, null, null, null, null, null); 050 } 051 052 public DefaultRelatedExpression(final boolean isEffectivelyFinal, final Supplier<QI> nameSupplier, 053 final N relatedExpression, final RelatedExpressionStrategy<N, T, B, TB, S, QI, R> strategy, 054 final RelatedExpressionsSpi<N, ?, T, B, MB, TB, S, ?, QI, EV, PP, R> relatedExpressionsSpi, 055 final Function<S, B> nameBindingResolver, final Function<S, Integer> lengthOfTypeForTempVarFunction, 056 final BiFunction<S, Function<TB, T>, T> typeForTypeVarFunction, final Function<S, TB> typeResolver, 057 final BiPredicate<? super DefaultRelatedExpression<N, T, B, MB, TB, S, QI, EV, PP, R>, R> canBeUsedInsteadOfBiPredicate) { 058 this.isEffectivelyFinal = isEffectivelyFinal; 059 this.nameSupplier = nameSupplier; 060 this.relatedExpression = relatedExpression; 061 this.strategy = strategy; 062 this.relatedExpressionsSpi = relatedExpressionsSpi; 063 this.nameBindingResolver = nameBindingResolver; 064 this.lengthOfTypeForTempVarFunction = lengthOfTypeForTempVarFunction; 065 this.typeForTypeVarFunction = typeForTypeVarFunction; 066 this.typeResolver = typeResolver; 067 this.canBeUsedInsteadOfBiPredicate = canBeUsedInsteadOfBiPredicate; 068 } 069 070 @Override 071 public boolean isEffectivelyFinal() { 072 return isEffectivelyFinal; 073 } 074 075 @Override 076 public QI getName() { 077 return nameSupplier.get(); 078 } 079 080 @Override 081 public N getRelatedExpression() { 082 return relatedExpression; 083 } 084 085 @Override 086 public void setRelatedExpression(final N relatedExpression) { 087 this.relatedExpression = relatedExpression; 088 } 089 090 @Override 091 public RelatedExpressionStrategy<N, T, B, TB, S, QI, R> getStrategy() { 092 return strategy; 093 } 094 095 @Override 096 public B resolveNameBinding(final S scope) { 097 return nameBindingResolver.apply(scope); 098 } 099 100 @Override 101 public int getLengthOfTypeForTempVar(final S scope) { 102 return lengthOfTypeForTempVarFunction.apply(scope); 103 } 104 105 @Override 106 public T getTypeForTempVar(final S scope, final Function<TB, T> importRewrite) { 107 return typeForTypeVarFunction.apply(scope, importRewrite); 108 } 109 110 @Override 111 public TB resolveType(final S scope) { 112 return typeResolver.apply(scope); 113 } 114 115 @Override 116 public List<QI> getContainedNamesFromSurface() { 117 throw new RuntimeException("Not yet implemented"); 118 } 119 120 @Override 121 public List<QI> getPartNames() { 122 throw new RuntimeException("Not yet implemented"); 123 } 124 125 @Override 126 public List<QI> getAssociateNames() { 127 throw new RuntimeException("Not yet implemented"); 128 } 129 130 @Override 131 public List<TB> resolveContainedTypesFromSurface(final S scope) { 132 throw new RuntimeException("Not yet implemented"); 133 } 134 135 @Override 136 public List<TB> resolvePartTypes(final S scope) { 137 throw new RuntimeException("Not yet implemented"); 138 } 139 140 @Override 141 public List<TB> resolveAssociateTypes(final S scope) { 142 throw new RuntimeException("Not yet implemented"); 143 } 144 145 @Override 146 public boolean canBeUsedInsteadOf(final R other) { 147 return canBeUsedInsteadOfBiPredicate.test(this, other); 148 } 149 150 @Override 151 public String getDescription() { 152 return relatedExpressionsSpi.getDescription(relatedExpression); 153 } 154 155 @Override 156 public int getLine() { 157 return relatedExpressionsSpi.getLine(relatedExpression); 158 } 159 160 @Override 161 public int getColumn() { 162 return relatedExpressionsSpi.getColumn(relatedExpression); 163 } 164 165 @Override 166 public int hashCode() { 167 final int prime = 31; 168 int result = 1; 169 result = prime * result + ((this.relatedExpression == null) ? 0 : this.relatedExpression.hashCode()); 170 result = prime * result + ((this.strategy == null) ? 0 : this.strategy.hashCode()); 171 return result; 172 } 173 174 @Override 175 public boolean equals(final Object obj) { 176 if (this == obj) { 177 return true; 178 } 179 if (obj == null) { 180 return false; 181 } 182 if (getClass() != obj.getClass()) { 183 return false; 184 } 185 @SuppressWarnings("unchecked") 186 final DefaultRelatedExpression<N, T, B, MB, TB, S, QI, EV, PP, R> other = (DefaultRelatedExpression<N, T, B, MB, TB, S, QI, EV, PP, R>) obj; 187 if (this.relatedExpression == null) { 188 if (other.relatedExpression != null) { 189 return false; 190 } 191 } else if (!relatedExpressionsSpi.compare(this.relatedExpression, other.relatedExpression)) { 192 return false; 193 } 194 if (this.strategy == null) { 195 if (other.strategy != null) { 196 return false; 197 } 198 } else if (!this.strategy.equals(other.strategy)) { 199 return false; 200 } 201 return true; 202 } 203 204 @Override 205 public String toString() { 206 return "RelatedExpression [name=" + this.getName() + ", relatedExpression=" + this.relatedExpression 207 + ", strategy=" + this.strategy + "]"; 208 } 209 210}