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

com.appland.appmap.transform.annotations.ArgumentArraySystem Maven / Gradle / Ivy

package com.appland.appmap.transform.annotations;

import com.appland.appmap.output.v1.Parameters;
import com.appland.appmap.output.v1.Value;
import javassist.CtBehavior;

import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class ArgumentArraySystem extends BaseSystem {
  private static final Boolean DEFAULT_VALUE = false;

  private Boolean wantsArgumentArray;

  private ArgumentArraySystem(CtBehavior hookBehavior, Boolean wantsArgumentArray) {
    super(hookBehavior);
    this.wantsArgumentArray = wantsArgumentArray;
  }

  /**
   * Factory method. Reads any relevant annotation information and caches it.
   * @param hookBehavior The hook behavior
   * @return A new ArgumentArraySystem
   */
  public static ISystem from(CtBehavior hookBehavior) {
    final Boolean wantsArgumentArray = (Boolean) AnnotationUtil.getValue(hookBehavior,
        ArgumentArray.class,
        DEFAULT_VALUE);
    return new ArgumentArraySystem(hookBehavior, wantsArgumentArray);
  }

  @Override
  public void mutateRuntimeParameters(HookBinding binding, Parameters runtimeParameters) {
    if (!this.wantsArgumentArray) {
      runtimeParameters.add(new Value().setName("$$"));
      return;
    }

    final Parameters targetParameters = binding.getTargetParameters();
    Value argArray = new Value();
    if (targetParameters.size() == 0) {
      argArray.setName("new Object[0]");
    } else {
      final String args = IntStream
          .range(1, targetParameters.size() + 1)
          .mapToObj(i -> {
            return String.format("com.appland.appmap.process.RuntimeUtil.boxValue($%d)", i);
          })
          .collect(Collectors.joining(", ", "new Object[]{ ", " }"));
      argArray.setName(args);
    }
    runtimeParameters.add(argArray);
  }

  @Override
  public Integer getParameterPriority() {
    return 300;
  }

  @Override
  public Boolean validate(Hook hook) {
    final Parameters hookParameters = hook.getParameters();
    if (this.wantsArgumentArray) {
      return hookParameters.validate(hookParameters.size() - 1, "java.lang.Object[]");
    }
    return true;
  }

  @Override
  public Boolean validate(HookBinding binding) {
    if (this.wantsArgumentArray) {
      return true;
    }

    final Parameters hookParameters = binding.getHook().getParameters();
    final Parameters targetParameters = binding.getTargetParameters();
    final Integer numParams = hookParameters.size(); // 2
    final Integer startIndex = hookParameters.size() - targetParameters.size(); // 2

    if (numParams - startIndex != targetParameters.size()) { // 0
      return false;
    }

    try {
      for (int i = startIndex; i < numParams; ++i) {
        Value hookParam = hookParameters.get(i);
        if (!targetParameters.validate(i - startIndex, hookParam.classType)) {
          return false;
        }
      }
    } catch (NoSuchElementException e) {
      return false;
    }

    return true;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy