Home | History | Annotate | Download | only in commands
      1 /*******************************************************************************
      2  * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  *
      8  * Contributors:
      9  *    Marc R. Hoffmann - initial API and implementation
     10  *
     11  *******************************************************************************/
     12 package org.jacoco.cli.internal.commands;
     13 
     14 import java.io.File;
     15 import java.io.IOException;
     16 import java.io.PrintWriter;
     17 import java.util.ArrayList;
     18 import java.util.Iterator;
     19 import java.util.List;
     20 
     21 import org.jacoco.cli.internal.Command;
     22 import org.jacoco.core.analysis.Analyzer;
     23 import org.jacoco.core.analysis.IClassCoverage;
     24 import org.jacoco.core.analysis.ICounter;
     25 import org.jacoco.core.analysis.ICoverageNode;
     26 import org.jacoco.core.analysis.ICoverageVisitor;
     27 import org.jacoco.core.analysis.ILine;
     28 import org.jacoco.core.analysis.IMethodCoverage;
     29 import org.jacoco.core.data.ExecutionDataStore;
     30 import org.kohsuke.args4j.Argument;
     31 import org.kohsuke.args4j.Option;
     32 
     33 /**
     34  * The <code>classinfo</code> command.
     35  */
     36 public class ClassInfo extends Command {
     37 
     38 	@Argument(usage = "location of Java class files", metaVar = "<classlocations>")
     39 	List<File> classfiles = new ArrayList<File>();
     40 
     41 	@Option(name = "--verbose", usage = "show method and line number details")
     42 	boolean verbose = false;
     43 
     44 	@Override
     45 	public String description() {
     46 		return "Print information about Java class files at the provided location.";
     47 	}
     48 
     49 	@Override
     50 	public int execute(final PrintWriter out, final PrintWriter err)
     51 			throws IOException {
     52 		if (classfiles.isEmpty()) {
     53 			out.println("[WARN] No class files provided.");
     54 		} else {
     55 			final Analyzer analyzer = new Analyzer(new ExecutionDataStore(),
     56 					new Printer(out));
     57 			for (final File file : classfiles) {
     58 				analyzer.analyzeAll(file);
     59 			}
     60 		}
     61 		return 0;
     62 	}
     63 
     64 	private class Printer implements ICoverageVisitor {
     65 
     66 		private final PrintWriter out;
     67 
     68 		Printer(final PrintWriter out) {
     69 			this.out = out;
     70 			out.println("  INST   BRAN   LINE   METH   CXTY   ELEMENT");
     71 		}
     72 
     73 		public void visitCoverage(final IClassCoverage coverage) {
     74 			final String desc = String.format("class 0x%016x %s",
     75 					Long.valueOf(coverage.getId()), coverage.getName());
     76 			printDetails(desc, coverage);
     77 			if (verbose) {
     78 				for (final Iterator<IMethodCoverage> i = coverage.getMethods()
     79 						.iterator(); i.hasNext();) {
     80 					printMethod(i.next(), i.hasNext());
     81 				}
     82 			}
     83 		}
     84 
     85 		private void printMethod(final IMethodCoverage method,
     86 				final boolean more) {
     87 			final String desc = String.format("+- method %s%s",
     88 					method.getName(), method.getDesc());
     89 			printDetails(desc, method);
     90 			for (int nr = method.getFirstLine(); nr <= method
     91 					.getLastLine(); nr++) {
     92 				printLine(method.getLine(nr), nr, more ? "| " : "  ");
     93 			}
     94 		}
     95 
     96 		private void printLine(final ILine line, final int nr,
     97 				final String indent) {
     98 			if (line.getStatus() != ICounter.EMPTY) {
     99 				out.printf("%6s %6s                        %s +- line %s%n",
    100 						total(line.getInstructionCounter()),
    101 						total(line.getBranchCounter()), indent,
    102 						Integer.valueOf(nr));
    103 			}
    104 		}
    105 
    106 		private void printDetails(final String description,
    107 				final ICoverageNode coverage) {
    108 			out.printf("%6s %6s %6s %6s %6s   %s%n",
    109 					total(coverage.getInstructionCounter()),
    110 					total(coverage.getBranchCounter()),
    111 					total(coverage.getLineCounter()),
    112 					total(coverage.getMethodCounter()),
    113 					total(coverage.getComplexityCounter()), description);
    114 		}
    115 
    116 		private String total(final ICounter counter) {
    117 			return String.valueOf(counter.getTotalCount());
    118 		}
    119 
    120 	}
    121 
    122 }
    123