All Downloads are FREE. Search and download functionalities are using the official Maven repository.

proguard.evaluation.value.ParticularValueFactory Maven / Gradle / Ivy

Go to download

ProGuardCORE is a free library to read, analyze, modify, and write Java class files.

There is a newer version: 9.1.6
Show newest version
/*
 * ProGuardCORE -- library to process Java bytecode.
 *
 * Copyright (c) 2002-2023 Guardsquare NV
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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 proguard.evaluation.value;

import org.jetbrains.annotations.NotNull;
import proguard.analysis.datastructure.CodeLocation;
import proguard.classfile.Clazz;
import proguard.classfile.Method;
import proguard.evaluation.value.object.AnalyzedObject;

/**
 * This class provides methods to create and reuse Value instances that have particular values,
 * whenever they are known.
 */
public class ParticularValueFactory extends BasicValueFactory implements ValueFactory {
  // Shared copies of Value objects, to avoid creating a lot of objects.
  static final IntegerValue INTEGER_VALUE_M1 = new ParticularIntegerValue(-1);
  static final IntegerValue INTEGER_VALUE_0 = new ParticularIntegerValue(0);
  static final IntegerValue INTEGER_VALUE_1 = new ParticularIntegerValue(1);
  static final IntegerValue INTEGER_VALUE_2 = new ParticularIntegerValue(2);
  static final IntegerValue INTEGER_VALUE_3 = new ParticularIntegerValue(3);
  static final IntegerValue INTEGER_VALUE_4 = new ParticularIntegerValue(4);
  static final IntegerValue INTEGER_VALUE_5 = new ParticularIntegerValue(5);
  static final LongValue LONG_VALUE_0 = new ParticularLongValue(0);
  static final LongValue LONG_VALUE_1 = new ParticularLongValue(1);
  static final FloatValue FLOAT_VALUE_0 = new ParticularFloatValue(0.0f);
  static final FloatValue FLOAT_VALUE_1 = new ParticularFloatValue(1.0f);
  static final FloatValue FLOAT_VALUE_2 = new ParticularFloatValue(2.0f);
  static final DoubleValue DOUBLE_VALUE_0 = new ParticularDoubleValue(0.0);
  static final DoubleValue DOUBLE_VALUE_1 = new ParticularDoubleValue(1.0);

  private static final int POS_ZERO_FLOAT_BITS = Float.floatToIntBits(0.0f);
  private static final long POS_ZERO_DOUBLE_BITS = Double.doubleToLongBits(0.0);

  private final ValueFactory arrayReferenceValueFactory;
  // if set to true, a ParticularReferenceValue will be created for each reference. Otherwise, this
  // will be delegated to the referenceValueFactory.
  private final ValueFactory referenceValueFactory;

  /** Creates a new ParticularValueFactory which does not keep track of particular references. */
  public ParticularValueFactory() {
    this(new ArrayReferenceValueFactory(), new TypedReferenceValueFactory());
  }

  /**
   * Creates a new ParticularValueFactory, which uses the given valuefactory for both array and
   * non-array reference construction.
   */
  public ParticularValueFactory(ValueFactory referenceValueFactory) {
    this(referenceValueFactory, referenceValueFactory);
  }

  /**
   * Creates a new ParticularValueFactory.
   *
   * @param arrayReferenceValueFactory the valuefactory to delegate new array references to.
   * @param referenceValueFactory the valuefactory to delegate new references to.
   */
  public ParticularValueFactory(
      ValueFactory arrayReferenceValueFactory, ValueFactory referenceValueFactory) {
    this.arrayReferenceValueFactory = arrayReferenceValueFactory;
    this.referenceValueFactory = referenceValueFactory;
  }

  // Implementations for ValueFactory.

  @Override
  public IntegerValue createIntegerValue(int value) {
    switch (value) {
      case -1:
        return INTEGER_VALUE_M1;
      case 0:
        return INTEGER_VALUE_0;
      case 1:
        return INTEGER_VALUE_1;
      case 2:
        return INTEGER_VALUE_2;
      case 3:
        return INTEGER_VALUE_3;
      case 4:
        return INTEGER_VALUE_4;
      case 5:
        return INTEGER_VALUE_5;
      default:
        return new ParticularIntegerValue(value);
    }
  }

  @Override
  public LongValue createLongValue(long value) {
    return value == 0L ? LONG_VALUE_0 : value == 1L ? LONG_VALUE_1 : new ParticularLongValue(value);
  }

  @Override
  public FloatValue createFloatValue(float value) {
    // Make sure to distinguish between +0.0 and -0.0.
    return value == 0.0f && Float.floatToIntBits(value) == POS_ZERO_FLOAT_BITS
        ? FLOAT_VALUE_0
        : value == 1.0f
            ? FLOAT_VALUE_1
            : value == 2.0f ? FLOAT_VALUE_2 : new ParticularFloatValue(value);
  }

  @Override
  public DoubleValue createDoubleValue(double value) {
    // Make sure to distinguish between +0.0 and -0.0.
    return value == 0.0 && Double.doubleToLongBits(value) == POS_ZERO_DOUBLE_BITS
        ? DOUBLE_VALUE_0
        : value == 1.0 ? DOUBLE_VALUE_1 : new ParticularDoubleValue(value);
  }

  @Override
  public ReferenceValue createReferenceValue() {
    return referenceValueFactory.createReferenceValue();
  }

  @Override
  public ReferenceValue createReferenceValueNull() {
    return referenceValueFactory.createReferenceValueNull();
  }

  @Override
  public ReferenceValue createReferenceValue(
      String type, Clazz referencedClass, boolean mayBeExtension, boolean mayBeNull) {
    return referenceValueFactory.createReferenceValue(
        type, referencedClass, mayBeExtension, mayBeNull);
  }

  /**
   * Deprecated, use {@link ParticularValueFactory#createReferenceValue(Clazz, boolean, boolean,
   * AnalyzedObject)}.
   */
  @Override
  @Deprecated
  public ReferenceValue createReferenceValue(
      String type, Clazz referencedClass, boolean mayBeExtension, boolean mayBeNull, Object value) {
    return referenceValueFactory.createReferenceValue(
        type, referencedClass, mayBeExtension, mayBeNull, value);
  }

  @Override
  public ReferenceValue createReferenceValue(
      Clazz referencedClass,
      boolean mayBeExtension,
      boolean mayBeNull,
      @NotNull AnalyzedObject value) {
    checkReferenceValue(value);
    return referenceValueFactory.createReferenceValue(
        referencedClass, mayBeExtension, mayBeNull, value);
  }

  @Override
  public ReferenceValue createReferenceValue(
      String type,
      Clazz referencedClass,
      boolean mayBeExtension,
      boolean mayBeNull,
      Clazz creationClass,
      Method creationMethod,
      int creationOffset) {
    return referenceValueFactory.createReferenceValue(
        type,
        referencedClass,
        mayBeExtension,
        mayBeNull,
        creationClass,
        creationMethod,
        creationOffset);
  }

  /**
   * Deprecated, use {@link ParticularValueFactory#createReferenceValue(Clazz, boolean, boolean,
   * CodeLocation, AnalyzedObject)}
   */
  @Override
  @Deprecated
  public ReferenceValue createReferenceValue(
      String type,
      Clazz referencedClass,
      boolean mayBeExtension,
      boolean mayBeNull,
      Clazz creationClass,
      Method creationMethod,
      int creationOffset,
      Object value) {
    return referenceValueFactory.createReferenceValue(
        type,
        referencedClass,
        mayBeExtension,
        mayBeNull,
        creationClass,
        creationMethod,
        creationOffset,
        value);
  }

  @Override
  public ReferenceValue createReferenceValue(
      Clazz referencedClass,
      boolean mayBeExtension,
      boolean mayBeNull,
      CodeLocation creationLocation,
      @NotNull AnalyzedObject value) {
    checkReferenceValue(value);
    checkCreationLocation(creationLocation);
    return referenceValueFactory.createReferenceValue(
        referencedClass, mayBeExtension, mayBeNull, creationLocation, value);
  }

  /**
   * Deprecated, use {@link ParticularValueFactory#createReferenceValueForId(Clazz, boolean,
   * boolean, Object, AnalyzedObject)}.
   */
  @Override
  @Deprecated
  public ReferenceValue createReferenceValueForId(
      String type,
      Clazz referencedClass,
      boolean mayBeExtension,
      boolean mayBeNull,
      Object id,
      Object value) {
    return referenceValueFactory.createReferenceValueForId(
        type, referencedClass, mayBeExtension, mayBeNull, id, value);
  }

  @Override
  public ReferenceValue createReferenceValueForId(
      Clazz referencedClass,
      boolean mayBeExtension,
      boolean mayBeNull,
      Object id,
      @NotNull AnalyzedObject value) {
    checkReferenceValue(value);
    return referenceValueFactory.createReferenceValueForId(
        referencedClass, mayBeExtension, mayBeNull, id, value);
  }

  @Override
  public ReferenceValue createReferenceValueForId(
      String type, Clazz referencedClass, boolean mayBeExtension, boolean mayBeNull, Object id) {
    return referenceValueFactory.createReferenceValueForId(
        type, referencedClass, mayBeExtension, mayBeNull, id);
  }

  @Override
  public ReferenceValue createArrayReferenceValue(
      String type, Clazz referencedClass, IntegerValue arrayLength) {
    return arrayReferenceValueFactory.createArrayReferenceValue(type, referencedClass, arrayLength);
  }

  @Override
  public ReferenceValue createArrayReferenceValue(
      String type, Clazz referencedClass, IntegerValue arrayLength, Object elementValues) {
    return arrayReferenceValueFactory.createArrayReferenceValue(
        type, referencedClass, arrayLength, elementValues);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy