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

org.checkerframework.common.value.JavaExpressionOptimizer Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java's type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.43.0
Show newest version
package org.checkerframework.common.value;

import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.type.TypeKind;
import org.checkerframework.dataflow.expression.FieldAccess;
import org.checkerframework.dataflow.expression.JavaExpression;
import org.checkerframework.dataflow.expression.JavaExpressionConverter;
import org.checkerframework.dataflow.expression.LocalVariable;
import org.checkerframework.dataflow.expression.MethodCall;
import org.checkerframework.dataflow.expression.ValueLiteral;
import org.checkerframework.framework.type.AnnotatedTypeFactory;

/**
 * Optimize the given JavaExpression. If the supplied factory is a {@code
 * ValueAnnotatedTypeFactory}, this implementation replaces any expression that the factory has an
 * exact value for, and does a small (not exhaustive) amount of constant-folding as well. If the
 * factory is some other factory, less optimization occurs.
 */
public class JavaExpressionOptimizer extends JavaExpressionConverter {

  /**
   * Annotated type factory. If it is a {@code ValueAnnotatedTypeFactory}, then more optimizations
   * are possible.
   */
  private final AnnotatedTypeFactory factory;

  /**
   * Creates a JavaExpressionOptimizer.
   *
   * @param factory an annotated type factory
   */
  public JavaExpressionOptimizer(AnnotatedTypeFactory factory) {
    this.factory = factory;
  }

  @Override
  protected JavaExpression visitFieldAccess(FieldAccess fieldAccessExpr, Void unused) {
    // Replace references to compile-time constant fields by the constant itself.
    if (fieldAccessExpr.isFinal()) {
      Object constant = fieldAccessExpr.getField().getConstantValue();
      if (constant != null && !(constant instanceof String)) {
        return new ValueLiteral(fieldAccessExpr.getType(), constant);
      }
    }
    return super.visitFieldAccess(fieldAccessExpr, unused);
  }

  @Override
  protected JavaExpression visitLocalVariable(LocalVariable localVarExpr, Void unused) {
    if (factory instanceof ValueAnnotatedTypeFactory) {
      Element element = localVarExpr.getElement();
      Long exactValue =
          ValueCheckerUtils.getExactValue(element, (ValueAnnotatedTypeFactory) factory);
      if (exactValue != null) {
        return new ValueLiteral(localVarExpr.getType(), exactValue.intValue());
      }
    }
    return super.visitLocalVariable(localVarExpr, unused);
  }

  @Override
  protected JavaExpression visitMethodCall(MethodCall methodCallExpr, Void unused) {
    JavaExpression optReceiver = convert(methodCallExpr.getReceiver());
    List optArguments = convert(methodCallExpr.getArguments());
    // Length of string literal: convert it to an integer literal.
    if (methodCallExpr.getElement().getSimpleName().contentEquals("length")
        && optReceiver instanceof ValueLiteral) {
      Object value = ((ValueLiteral) optReceiver).getValue();
      if (value instanceof String) {
        return new ValueLiteral(
            factory.types.getPrimitiveType(TypeKind.INT), ((String) value).length());
      }
    }
    return new MethodCall(
        methodCallExpr.getType(), methodCallExpr.getElement(), optReceiver, optArguments);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy