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

com.undefinedlabs.scope.coverage.utils.CoverageAnalyzerUtils Maven / Gradle / Ivy

package com.undefinedlabs.scope.coverage.utils;

import com.undefinedlabs.scope.logger.ScopeLogger;
import com.undefinedlabs.scope.logger.ScopeLoggerResolver;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.LineNumber;
import org.apache.bcel.classfile.LineNumberTable;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.MethodGen;

public enum CoverageAnalyzerUtils {
  INSTANCE;

  private static final ScopeLogger LOGGER = ScopeLoggerResolver.INSTANCE.get();
  private static final ConcurrentMap> linesPerClassName =
      new ConcurrentHashMap<>();

  public List buildAllLinesPerClassName(final String className) {
    final List storedLines = linesPerClassName.get(className);
    if (storedLines != null) {
      return storedLines;
    }

    try {
      final JavaClass javaClass = Repository.lookupClass(className);
      final List lines = new ArrayList<>();
      for (final Method bcelMethod : javaClass.getMethods()) {
        final MethodGen methodGen =
            new MethodGen(
                bcelMethod, javaClass.getClassName(), new ClassGen(javaClass).getConstantPool());
        final LineNumberTable lineNumberTable =
            methodGen.getLineNumberTable(methodGen.getConstantPool());

        for (final LineNumber lineNumber : lineNumberTable.getLineNumberTable()) {
          lines.add(lineNumber.getLineNumber());
        }

        Collections.sort(lines);
        linesPerClassName.putIfAbsent(className, lines);
      }
      return lines;
    } catch (final Exception e) {
      LOGGER.error(
          "[COVERAGE] Error calculating all source code lines for class: '"
              + className
              + "'. Exception: "
              + e);
      return Collections.emptyList();
    }
  }

  public Map> buildAllLinesPerClassName(final Set classNames) {
    final Map> allLinesPerClassMap = new HashMap<>();

    for (final String className : classNames) {
      final List lines = buildAllLinesPerClassName(className);
      if (lines.size() == 0) {
        LOGGER.trace(
            "--- Coverage: It could not be possible to detect executable lines for class '"
                + className
                + "'");
        continue;
      }

      allLinesPerClassMap.put(className, lines);
    }

    return allLinesPerClassMap;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy