001package daikon.derive.binary;
002
003import daikon.ProglangType;
004import daikon.VarComparability;
005import daikon.VarInfo;
006import java.util.logging.Level;
007import java.util.logging.Logger;
008import org.checkerframework.checker.nullness.qual.Nullable;
009
010/** Factory for SequencesConcat derived variables. */
011public final class SequencesConcatFactory extends BinaryDerivationFactory {
012
013  /** Debug tracer. */
014  public static final Logger debug =
015      Logger.getLogger("daikon.derive.binary.SequencesConcatFactory");
016
017  @Override
018  public BinaryDerivation @Nullable [] instantiate(VarInfo var1, VarInfo var2) {
019
020    boolean enabled = SequencesConcat.dkconfig_enabled;
021    if (!enabled) {
022      return null;
023    }
024
025    if (var1.type != var2.type || var1.rep_type != var2.rep_type) {
026      // Is this really necessary since we're checking comparability?
027      return null;
028    }
029
030    if (var1.rep_type != ProglangType.INT_ARRAY
031        && var1.rep_type != ProglangType.STRING_ARRAY
032        && var1.rep_type != ProglangType.DOUBLE_ARRAY) {
033      return null;
034    }
035
036    if (!VarComparability.comparable(var1, var2)) {
037      return null;
038    }
039
040    if (var1.derived != null || var2.derived != null) {
041      // From derived variables.  Don't derive.
042      return null;
043    }
044
045    // We don't want concats of arrays with themselves
046    if (var1.name().equals(var2.name())) {
047      return null;
048    }
049
050    if (debug.isLoggable(Level.FINE)) {
051      debug.fine(
052          var1.ppt + ": " + var1.name() + " and " + var2.name() + " are worth deriving from");
053      debug.fine("Types are: " + var1.type + " " + var2.type);
054      debug.fine("Comparabilities are: " + var1.comparability + " " + var2.comparability);
055    }
056
057    return new BinaryDerivation[] {
058      new SequencesConcat(var1, var2),
059    };
060  }
061}