private FileCoverageInformation getFileInfoTarget(
      final FileLocation pLoc, final Map<String, FileCoverageInformation> pTargets) {

    assert pLoc.getStartingLineNumber()
        != 0; // Cannot produce coverage info for dummy file location

    String file = pLoc.getFileName();
    FileCoverageInformation fileInfos = pTargets.get(file);

    if (fileInfos == null) {
      fileInfos = new FileCoverageInformation();
      pTargets.put(file, fileInfos);
    }

    return fileInfos;
  }
  private void handleCoveredEdge(
      final CFAEdge pEdge, final Map<String, FileCoverageInformation> pCollectors) {

    FileLocation loc = pEdge.getFileLocation();
    if (loc.getStartingLineNumber() == 0) {
      return;
    }
    if (pEdge instanceof ADeclarationEdge
        && (((ADeclarationEdge) pEdge).getDeclaration() instanceof AFunctionDeclaration)) {
      return;
    }

    final FileCoverageInformation collector = getFileInfoTarget(loc, pCollectors);

    if (pEdge instanceof AssumeEdge) {
      collector.addVisitedAssume((AssumeEdge) pEdge);
    }

    collector.addVisitedLine(pEdge.getLineNumber());
  }
示例#3
0
  public static FileLocation merge(List<FileLocation> locations) {
    checkArgument(!Iterables.isEmpty(locations));

    String fileName = null;
    String niceFileName = null;
    int startingLine = Integer.MAX_VALUE;
    int startingLineInOrigin = Integer.MAX_VALUE;
    int endingLine = Integer.MIN_VALUE;
    int endingLineInOrigin = Integer.MIN_VALUE;
    for (FileLocation loc : locations) {
      if (loc == DUMMY) {
        continue;
      }
      if (fileName == null) {
        fileName = loc.fileName;
        niceFileName = loc.niceFileName;
      } else if (!fileName.equals(loc.fileName)) {
        return MULTIPLE_FILES;
      }

      startingLine = Math.min(startingLine, loc.getStartingLineNumber());
      startingLineInOrigin = Math.min(startingLineInOrigin, loc.getStartingLineInOrigin());
      endingLine = Math.max(endingLine, loc.getEndingLineNumber());
      endingLineInOrigin = Math.max(endingLineInOrigin, loc.getEndingLineInOrigin());
    }

    if (fileName == null) {
      // only DUMMY elements
      return DUMMY;
    }
    return new FileLocation(
        fileName,
        niceFileName,
        0,
        0,
        startingLine,
        endingLine,
        startingLineInOrigin,
        endingLineInOrigin);
  }
  private void handleExistedEdge(
      final CFAEdge pEdge, final Map<String, FileCoverageInformation> pCollectors) {

    final FileLocation loc = pEdge.getFileLocation();
    if (loc.getStartingLineNumber() == 0) {
      // dummy location
      return;
    }
    if (pEdge instanceof ADeclarationEdge
        && (((ADeclarationEdge) pEdge).getDeclaration() instanceof AFunctionDeclaration)) {
      // Function declarations span the complete body, this is not desired.
      return;
    }

    final FileCoverageInformation collector = getFileInfoTarget(loc, pCollectors);

    if (pEdge instanceof AssumeEdge) {
      collector.addExistingAssume((AssumeEdge) pEdge);
    }

    collector.addExistingLine(pEdge.getLineNumber());
  }
  public void writeCoverageReport(
      final PrintStream pStatisticsOutput, final ReachedSet pReached, final CFA pCfa) {

    if (!enabled) {
      return;
    }

    Multiset<FunctionEntryNode> reachedLocations = getFunctionEntriesFromReached(pReached);

    Map<String, FileCoverageInformation> infosPerFile = new HashMap<>();

    // Add information about existing functions
    for (FunctionEntryNode entryNode : pCfa.getAllFunctionHeads()) {
      final FileLocation loc = entryNode.getFileLocation();
      if (loc.getStartingLineNumber() == 0) {
        // dummy location
        continue;
      }
      final String functionName = entryNode.getFunctionName();
      final FileCoverageInformation infos = getFileInfoTarget(loc, infosPerFile);

      final int startingLine = loc.getStartingLineInOrigin();
      final int endingLine = loc.getEndingLineInOrigin();

      infos.addExistingFunction(functionName, startingLine, endingLine);

      if (reachedLocations.contains(entryNode)) {
        infos.addVisitedFunction(entryNode.getFunctionName(), reachedLocations.count(entryNode));
      }
    }

    // Add information about existing locations
    for (CFANode node : pCfa.getAllNodes()) {
      for (int i = 0; i < node.getNumLeavingEdges(); i++) {
        handleExistedEdge(node.getLeavingEdge(i), infosPerFile);
      }
    }

    Set<CFANode> reachedNodes =
        from(pReached).transform(EXTRACT_LOCATION).filter(notNull()).toSet();
    // Add information about visited locations
    for (AbstractState state : pReached) {
      ARGState argState = AbstractStates.extractStateByType(state, ARGState.class);
      if (argState != null) {
        for (ARGState child : argState.getChildren()) {
          if (!child.isCovered()) {
            List<CFAEdge> edges = argState.getEdgesToChild(child);
            if (edges.size() > 1) {
              for (CFAEdge innerEdge : edges) {
                handleCoveredEdge(innerEdge, infosPerFile);
              }

              // BAM produces paths with no edge connection thus the list will be empty
            } else if (!edges.isEmpty()) {
              handleCoveredEdge(Iterables.getOnlyElement(edges), infosPerFile);
            }
          }
        }
      } else {
        // Simple kind of analysis
        // Cover all edges from reached nodes
        // It is less precise, but without ARG it is impossible to know what path we chose
        CFANode node = AbstractStates.extractLocation(state);
        for (int i = 0; i < node.getNumLeavingEdges(); i++) {
          CFAEdge edge = node.getLeavingEdge(i);
          if (reachedNodes.contains(edge.getSuccessor())) {
            handleCoveredEdge(edge, infosPerFile);
          }
        }
      }
    }

    for (CoverageWriter w : reportWriters) {
      w.write(infosPerFile, pStatisticsOutput);
    }
  }