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

org.checkerframework.common.util.count.JavaCodeStatistics 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.49.1-eisop1
Show newest version
package org.checkerframework.common.util.count;

import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.ArrayAccessTree;
import com.sun.source.tree.AssertTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.NewArrayTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.ParameterizedTypeTree;
import com.sun.source.tree.TypeCastTree;
import com.sun.tools.javac.util.Log;

import org.checkerframework.framework.source.SourceChecker;
import org.checkerframework.framework.source.SourceVisitor;
import org.checkerframework.javacutil.AnnotationProvider;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.TreeUtils;

import java.util.List;

import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;

/**
 * An annotation processor for counting a few specific aspects about the size of Java code:
 *
 * 
    *
  • The number of type parameter declarations and uses. *
  • The number of array accesses and dimensions in array creations. *
  • The number of type casts. *
* *

To invoke it, use * *

 * javac -proc:only -processor org.checkerframework.common.util.count.JavaCodeStatistics MyFile.java ...
 * 
* * @see AnnotationStatistics * @see org.checkerframework.common.util.report.ReportChecker */ @SupportedSourceVersion(SourceVersion.RELEASE_8) public class JavaCodeStatistics extends SourceChecker { /** The number of type parameter declarations and uses. */ int generics = 0; /** The number of array accesses and dimensions in array creations. */ int arrayAccesses = 0; /** The number of type casts. */ int typecasts = 0; String[] warningKeys = { "index", "lowerbound", "samelen", "searchindex", "substringindex", "upperbound" }; /** * The number of warning suppressions with at least one key that matches one of the Index * Checker subcheckers. */ int numberOfIndexWarningSuppressions = 0; /** The SuppressWarnings.value field/element. */ final ExecutableElement suppressWarningsValueElement = TreeUtils.getMethod(SuppressWarnings.class, "value", 0, processingEnv); /** Creates a JavaCodeStatistics. */ public JavaCodeStatistics() { // This checker never issues any warnings, so don't warn about // @SuppressWarnings("allcheckers:..."). this.useAllcheckersPrefix = false; } @Override public void typeProcessingOver() { Log log = getCompilerLog(); if (log.nerrors != 0) { System.out.printf("Not outputting statistics, because compilation issued an error.%n"); } else { System.out.printf("Found %d generic type uses.%n", generics); System.out.printf("Found %d array accesses and creations.%n", arrayAccesses); System.out.printf("Found %d typecasts.%n", typecasts); System.out.printf( "Found %d warning suppression annotations for the Index Checker.%n", numberOfIndexWarningSuppressions); } super.typeProcessingOver(); } @Override protected SourceVisitor createSourceVisitor() { return new Visitor(this); } class Visitor extends SourceVisitor { public Visitor(JavaCodeStatistics l) { super(l); } @Override public Void visitAnnotation(AnnotationTree tree, Void aVoid) { AnnotationMirror annotationMirror = TreeUtils.annotationFromAnnotationTree(tree); if (AnnotationUtils.annotationName(annotationMirror) .equals(SuppressWarnings.class.getCanonicalName())) { List keys = AnnotationUtils.getElementValueArray( annotationMirror, suppressWarningsValueElement, String.class); for (String foundKey : keys) { for (String indexKey : warningKeys) { if (foundKey.startsWith(indexKey)) { numberOfIndexWarningSuppressions++; return super.visitAnnotation(tree, aVoid); } } } } return super.visitAnnotation(tree, aVoid); } @Override public Void visitAssert(AssertTree tree, Void aVoid) { ExpressionTree detail = tree.getDetail(); if (detail != null) { String msg = detail.toString(); for (String indexKey : warningKeys) { String key = "@AssumeAssertion(" + indexKey; if (msg.contains(key)) { numberOfIndexWarningSuppressions++; return super.visitAssert(tree, aVoid); } } } return super.visitAssert(tree, aVoid); } @Override public Void visitClass(ClassTree tree, Void p) { if (shouldSkipDefs(tree)) { // Not "return super.visitClass(classTree, p);" because that would recursively call // visitors on subtrees; we want to skip the class entirely. return null; } generics += tree.getTypeParameters().size(); return super.visitClass(tree, p); } @Override public Void visitNewArray(NewArrayTree tree, Void aVoid) { arrayAccesses += tree.getDimensions().size(); return super.visitNewArray(tree, aVoid); } @Override public Void visitNewClass(NewClassTree tree, Void aVoid) { if (TreeUtils.isDiamondTree(tree)) { generics++; } generics += tree.getTypeArguments().size(); return super.visitNewClass(tree, aVoid); } @Override public Void visitMethodInvocation(MethodInvocationTree tree, Void aVoid) { generics += tree.getTypeArguments().size(); return super.visitMethodInvocation(tree, aVoid); } @Override public Void visitMethod(MethodTree tree, Void aVoid) { generics += tree.getTypeParameters().size(); return super.visitMethod(tree, aVoid); } @Override public Void visitParameterizedType(ParameterizedTypeTree tree, Void p) { generics += tree.getTypeArguments().size(); return super.visitParameterizedType(tree, p); } @Override public Void visitArrayAccess(ArrayAccessTree tree, Void aVoid) { arrayAccesses++; return super.visitArrayAccess(tree, aVoid); } @Override public Void visitTypeCast(TypeCastTree tree, Void aVoid) { typecasts++; return super.visitTypeCast(tree, aVoid); } } @Override public AnnotationProvider getAnnotationProvider() { throw new UnsupportedOperationException( "getAnnotationProvider is not implemented for this class."); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy