#!/bin/bash

# This command counts the approximate frequency of each distinct reason for
# warning suppressions.
# To invoke it, pass a type system name; for example:
#   count-suppressions nullness

# If warning suppression text contains a colon, this script prints only
# the text before the colon, under the assumption that the initial text
# is a category name.

# This script is useful to determine the most frequent reasons for warning
# suppressions, to help checker developers decide what featuers to add to
# their type systems.  However, use common.util.count.AnnotationStatistics
# to count the total number of warning suppressions (for example, to report
# in a paper), because this script gives only an approximate count.

debug=0

if [[ "$OSTYPE" == "darwin"* ]]; then
    SED=gsed
    GREP=ggrep
else
    SED=sed
    GREP=grep
fi

if [ "$#" -ne 1 ]; then
  echo "Usage: $0 TYPESYSTEM" >&2
  exit 1
fi

regex="$1"

# If argument is a compound checker, make the regex match them all.
if [ "$regex" = "nullness" ]; then
    regex="\(nullness\|initialization\|keyfor\)"
fi
if [ "$regex" = "index" ]; then
    regex="\(index\|lessthan\|lowerbound\|samelen\|searchindex\|substringindex\|upperbound\)"
fi

# Implementation notes:
# These are the two types of matching lines:
# Matching lines:
#  * "KEY"  (for @SuppressWarnings, but don't match "@SuppressWarnings"
#    because that might be on the previous line)
#  * @AssumeAssertion(key)

echo "regex=${regex}"

greplines=$(mktemp /tmp/count-suppressions.XXXXXX)
# This grep command captures a few stray lines; users should ignore them.
${GREP} -n --recursive --include='*.java' "\"${regex}[:\"]\(.*[^;]\)\?\(\$\|//\)\|@AssumeAssertion(${regex})" | grep -v "@AnnotatedFor" > ${greplines}
## Don't output a total, to avoid people using this approximate count.
# echo -n "Total: "
# cat ${greplines} | wc -l
cat ${greplines} \
    | ${SED} 's/.*\/\/ //g' \
    | ${SED} "s/.*@AssumeAssertion([^)])[ :]*\([^\"]\+\)\";/\1/g" \
    | ${SED} 's/\([^0-9]\): [^:].*/\1/' \
    | ${SED} 's/ \+$//' \
    | sort | uniq -c | sort -rg
if [ "$debug" -eq "0" ]; then
  rm -f ${greplines}
else
  echo Output is in: ${greplines}
fi
