Class CheckerMain


  • public class CheckerMain
    extends java.lang.Object
    This class behaves similarly to javac. CheckerMain does the following:
    • add the javac.jar to the runtime classpath of the process that runs the Checker Framework.
    • parse and implement any special options used by the Checker Framework, e.g., using "shortnames" for annotation processors
    • pass all remaining command-line arguments to the real javac
    To debug this class, use the -AoutputArgsToFile=FILENAME command-line argument or -AoutputArgsToFile=- to output to standard out.

    "To run the Checker Framework" really means to run java, where the program being run is javac and javac is passed a -processor command-line argument that mentions a Checker Framework checker. There are 5 relevant classpaths: The classpath and bootclasspath when running java, and the classpath, bootclasspath, and processorpath used by javac. The latter three are the only important ones.

    Note for developers: Try to limit the work done (and options interpreted) by CheckerMain, because its functionality is not available to users who choose not to use the Checker Framework javac script.

    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected static java.util.regex.Pattern BOOT_CLASS_PATH_REGEX
      A pattern to match bootclasspath prepend entries, used to construct one -Xbootclasspath/p: command-line argument.
      protected static java.lang.String CHECKER_BASE_DIR_NAME
      Processor shorthand is enabled for processors in this directory in checker.jar.
      static java.lang.String CHECKER_QUAL_PATH_OPT
      Option name for specifying an alternative checker-qual.jar location.
      static java.lang.String CHECKER_UTIL_PATH_OPT
      Option name for specifying an alternative checker-util.jar location.
      protected java.io.File checkerJar
      The path to the jar containing CheckerMain.class (i.e.
      protected java.io.File checkerQualJar
      The path to checker-qual.jar.
      protected java.io.File checkerUtilJar
      The path to checker-util.jar.
      protected static java.lang.String COMMON_BASE_DIR_NAME
      Processor shorthand is enabled for processors in this directory in checker.jar.
      static java.lang.String JAVAC_PATH_OPT
      Option name for specifying an alternative javac.jar location.
      protected java.io.File javacJar
      The path to the javacJar to use.
      static java.lang.String JDK_PATH_OPT
      Option name for specifying an alternative jdk.jar location.
      protected static java.util.regex.Pattern JVM_OPTS_REGEX
      Matches all -J arguments.
    • Constructor Summary

      Constructors 
      Constructor Description
      CheckerMain​(java.io.File checkerJar, java.util.List<java.lang.String> args)
      Construct all the relevant file locations and Java version given the path to this jar and a set of directories in which to search for jars.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected void addMainToArgs​(java.util.List<java.lang.String> args)  
      void addToClasspath​(java.util.List<java.lang.String> cpOpts)  
      void addToProcessorpath​(java.util.List<java.lang.String> ppOpts)  
      void addToRuntimeClasspath​(java.util.List<java.lang.String> runtimeClasspathOpts)  
      protected void assertValidState()
      Assert that required jars exist.
      protected java.util.List<java.io.File> collectArgFiles​(java.util.List<java.lang.String> args)
      Return the arguments that start with @ and therefore are files that contain javac arguments.
      protected java.util.List<java.lang.String> createCompilationBootclasspath​(java.util.List<java.lang.String> argsList)
      Returns the compilation bootclasspath from argsList.
      protected java.util.List<java.lang.String> createCpOpts​(java.util.List<java.lang.String> argsList)  
      protected java.util.List<java.lang.String> createPpOpts​(java.util.List<java.lang.String> argsList)
      Returns processor path options.
      protected java.util.List<java.lang.String> createRuntimeClasspath​(java.util.List<java.lang.String> argsList)  
      protected static java.util.List<java.lang.String> expandArgFiles​(java.util.List<java.io.File> files)
      Return all the lines in all the files.
      protected static @PolyNull java.lang.String extractArg​(java.lang.String argumentName, @PolyNull java.lang.String alternative, java.util.List<java.lang.String> args)
      Remove the argument given by argumentName and the subsequent value from the list args if present.
      protected static java.util.List<java.lang.String> extractBootClassPath​(java.util.List<java.lang.String> args)
      Remove all -Xbootclasspath/p: or -J-Xbootclasspath/p: arguments from args and add them to the returned list.
      protected static java.util.List<java.lang.String> extractCpOpts​(java.util.List<java.lang.String> args)
      Return the last -cp or -classpath option.
      protected static java.io.File extractFileArg​(java.lang.String argumentName, java.io.File alternative, java.util.List<java.lang.String> args)
      Remove the argument given by argumentName and the subsequent value from the list args if present.
      protected static java.util.List<java.lang.String> extractJvmOpts​(java.util.List<java.lang.String> args)
      Remove all -J arguments from args and add them to the returned list (without the -J prefix).
      protected static java.util.List<java.lang.String> extractOptWithPattern​(@Regex(1) java.util.regex.Pattern pattern, boolean allowEmpties, java.util.List<java.lang.String> args)
      Find all args that match the given pattern and extract their index 1 group.
      protected static java.util.List<java.lang.String> extractPpOpts​(java.util.List<java.lang.String> args)
      Remove the -processorpath options and their arguments from args.
      static java.lang.String findPathTo​(@Nullable java.lang.Class<?> cls, boolean errIfFromDirectory)
      Find the jar file or directory containing the .class file from which cls was loaded.
      java.util.List<java.lang.String> getExecArguments()
      Invoke the compiler with all relevant jars on its classpath and/or bootclasspath.
      int invokeCompiler()
      Invoke the compiler with all relevant jars on its classpath and/or bootclasspath.
      static void main​(java.lang.String[] args)
      Any exception thrown by the Checker Framework escapes to the command line.
      static boolean matchesCheckerOrSubcheckerFromList​(java.lang.String processorString, java.util.List<@FullyQualifiedName java.lang.String> fullyQualifiedCheckerNames)
      Returns true if processorString, once transformed into fully-qualified form, is present in fullyQualifiedCheckerNames.
      static boolean matchesFullyQualifiedProcessor​(java.lang.String processorName, java.util.List<@FullyQualifiedName java.lang.String> fullyQualifiedCheckerNames, boolean allowSubcheckers)
      Given a shorthand processor name, returns true if it can be expanded to a checker in the fullyQualifiedCheckerNames list.
      protected void replaceShorthandProcessor​(java.util.List<java.lang.String> args)
      For every "-processor" argument in args, replace its immediate successor argument using unabbreviateProcessorNames.
      protected static java.lang.String unshorthandProcessorNames​(java.lang.String processorsString, java.util.List<@FullyQualifiedName java.lang.String> fullyQualifiedCheckerNames, boolean allowSubcheckers)
      Takes a string of comma-separated processor names, and expands any shorthands to fully-qualified names from the fullyQualifiedCheckerNames list.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • javacJar

        protected final java.io.File javacJar
        The path to the javacJar to use.
      • checkerJar

        protected final java.io.File checkerJar
        The path to the jar containing CheckerMain.class (i.e. checker.jar).
      • checkerQualJar

        protected final java.io.File checkerQualJar
        The path to checker-qual.jar.
      • checkerUtilJar

        protected final java.io.File checkerUtilJar
        The path to checker-util.jar.
      • CHECKER_QUAL_PATH_OPT

        public static final java.lang.String CHECKER_QUAL_PATH_OPT
        Option name for specifying an alternative checker-qual.jar location. The accompanying value MUST be the path to the jar file (NOT the path to its encompassing directory)
        See Also:
        Constant Field Values
      • CHECKER_UTIL_PATH_OPT

        public static final java.lang.String CHECKER_UTIL_PATH_OPT
        Option name for specifying an alternative checker-util.jar location. The accompanying value MUST be the path to the jar file (NOT the path to its encompassing directory)
        See Also:
        Constant Field Values
      • JAVAC_PATH_OPT

        public static final java.lang.String JAVAC_PATH_OPT
        Option name for specifying an alternative javac.jar location. The accompanying value MUST be the path to the jar file (NOT the path to its encompassing directory)
        See Also:
        Constant Field Values
      • JDK_PATH_OPT

        public static final java.lang.String JDK_PATH_OPT
        Option name for specifying an alternative jdk.jar location. The accompanying value MUST be the path to the jar file (NOT the path to its encompassing directory)
        See Also:
        Constant Field Values
      • BOOT_CLASS_PATH_REGEX

        protected static final java.util.regex.Pattern BOOT_CLASS_PATH_REGEX
        A pattern to match bootclasspath prepend entries, used to construct one -Xbootclasspath/p: command-line argument.
      • JVM_OPTS_REGEX

        protected static final java.util.regex.Pattern JVM_OPTS_REGEX
        Matches all -J arguments.
      • CHECKER_BASE_DIR_NAME

        protected static final java.lang.String CHECKER_BASE_DIR_NAME
        Processor shorthand is enabled for processors in this directory in checker.jar.
        See Also:
        Constant Field Values
      • COMMON_BASE_DIR_NAME

        protected static final java.lang.String COMMON_BASE_DIR_NAME
        Processor shorthand is enabled for processors in this directory in checker.jar.
        See Also:
        Constant Field Values
    • Constructor Detail

      • CheckerMain

        public CheckerMain​(java.io.File checkerJar,
                           java.util.List<java.lang.String> args)
        Construct all the relevant file locations and Java version given the path to this jar and a set of directories in which to search for jars.
    • Method Detail

      • main

        public static void main​(java.lang.String[] args)
        Any exception thrown by the Checker Framework escapes to the command line.
        Parameters:
        args - command-line arguments
      • assertValidState

        protected void assertValidState()
        Assert that required jars exist.
      • addToClasspath

        public void addToClasspath​(java.util.List<java.lang.String> cpOpts)
      • addToProcessorpath

        public void addToProcessorpath​(java.util.List<java.lang.String> ppOpts)
      • addToRuntimeClasspath

        public void addToRuntimeClasspath​(java.util.List<java.lang.String> runtimeClasspathOpts)
      • createRuntimeClasspath

        protected java.util.List<java.lang.String> createRuntimeClasspath​(java.util.List<java.lang.String> argsList)
      • createCompilationBootclasspath

        protected java.util.List<java.lang.String> createCompilationBootclasspath​(java.util.List<java.lang.String> argsList)
        Returns the compilation bootclasspath from argsList.
        Parameters:
        argsList - args to add
        Returns:
        the compilation bootclasspath from argsList
      • createCpOpts

        protected java.util.List<java.lang.String> createCpOpts​(java.util.List<java.lang.String> argsList)
      • createPpOpts

        protected java.util.List<java.lang.String> createPpOpts​(java.util.List<java.lang.String> argsList)
        Returns processor path options.

        This method assumes that createCpOpts has already been run.

        Parameters:
        argsList - arguments
        Returns:
        processor path options
      • collectArgFiles

        protected java.util.List<java.io.File> collectArgFiles​(java.util.List<java.lang.String> args)
        Return the arguments that start with @ and therefore are files that contain javac arguments.
        Parameters:
        args - a list of command-line arguments; is not modified
        Returns:
        a List of files representing all arguments that started with @
      • extractArg

        protected static @PolyNull java.lang.String extractArg​(java.lang.String argumentName,
                                                               @PolyNull java.lang.String alternative,
                                                               java.util.List<java.lang.String> args)
        Remove the argument given by argumentName and the subsequent value from the list args if present. Return the subsequent value.
        Parameters:
        argumentName - a command-line option name whose argument to extract
        alternative - default value to return if argumentName does not appear in args
        args - the current list of arguments
        Returns:
        the string that follows argumentName if argumentName is in args, or alternative if argumentName is not present in args
      • extractFileArg

        protected static java.io.File extractFileArg​(java.lang.String argumentName,
                                                     java.io.File alternative,
                                                     java.util.List<java.lang.String> args)
        Remove the argument given by argumentName and the subsequent value from the list args if present. Return the subsequent value wrapped as a File.
        Parameters:
        argumentName - argument to extract
        alternative - file to return if argumentName is not found in args
        args - the current list of arguments
        Returns:
        the string that follows argumentName wrapped as a File if argumentName is in args or alternative if argumentName is not present in args
      • extractOptWithPattern

        protected static java.util.List<java.lang.String> extractOptWithPattern​(@Regex(1) java.util.regex.Pattern pattern,
                                                                                boolean allowEmpties,
                                                                                java.util.List<java.lang.String> args)
        Find all args that match the given pattern and extract their index 1 group. Add all the index 1 groups to the returned list. Remove all matching args from the input args list.
        Parameters:
        pattern - a pattern with at least one matching group
        allowEmpties - whether or not to add empty group(1) matches to the returned list
        args - the arguments to extract from
        Returns:
        a list of arguments from the first group that matched the pattern for each input args or the empty list if there were none
      • extractBootClassPath

        protected static java.util.List<java.lang.String> extractBootClassPath​(java.util.List<java.lang.String> args)
        Remove all -Xbootclasspath/p: or -J-Xbootclasspath/p: arguments from args and add them to the returned list.
        Parameters:
        args - the arguments to extract from
        Returns:
        all non-empty arguments matching BOOT_CLASS_PATH_REGEX or an empty list if there were none
      • extractJvmOpts

        protected static java.util.List<java.lang.String> extractJvmOpts​(java.util.List<java.lang.String> args)
        Remove all -J arguments from args and add them to the returned list (without the -J prefix).
        Parameters:
        args - the arguments to extract from
        Returns:
        all -J arguments (without the -J prefix) or an empty list if there were none
      • extractCpOpts

        protected static java.util.List<java.lang.String> extractCpOpts​(java.util.List<java.lang.String> args)
        Return the last -cp or -classpath option. If no -cp or -classpath arguments were present, then return the CLASSPATH environment variable (if set) followed by the current directory.

        Also removes all -cp and -classpath options from args.

        Parameters:
        args - a list of arguments to extract from; is side-effected by this
        Returns:
        collection of classpaths to concatenate to use when calling javac.jar
      • extractPpOpts

        protected static java.util.List<java.lang.String> extractPpOpts​(java.util.List<java.lang.String> args)
        Remove the -processorpath options and their arguments from args. Return the last argument.
        Parameters:
        args - a list of arguments to extract from
        Returns:
        the arguments that should be put on the processorpath when calling javac.jar
      • addMainToArgs

        protected void addMainToArgs​(java.util.List<java.lang.String> args)
      • getExecArguments

        public java.util.List<java.lang.String> getExecArguments()
        Invoke the compiler with all relevant jars on its classpath and/or bootclasspath.
      • invokeCompiler

        public int invokeCompiler()
        Invoke the compiler with all relevant jars on its classpath and/or bootclasspath.
      • expandArgFiles

        protected static java.util.List<java.lang.String> expandArgFiles​(java.util.List<java.io.File> files)
        Return all the lines in all the files.
        Parameters:
        files - a list of files
        Returns:
        a list of all the lines in all the files
      • findPathTo

        public static java.lang.String findPathTo​(@Nullable java.lang.Class<?> cls,
                                                  boolean errIfFromDirectory)
                                           throws java.lang.IllegalStateException
        Find the jar file or directory containing the .class file from which cls was loaded.
        Parameters:
        cls - the class whose .class file we wish to locate; if null, CheckerMain.class
        errIfFromDirectory - if false, throw an exception if the file was loaded from a directory
        Throws:
        java.lang.IllegalStateException
      • matchesCheckerOrSubcheckerFromList

        public static boolean matchesCheckerOrSubcheckerFromList​(java.lang.String processorString,
                                                                 java.util.List<@FullyQualifiedName java.lang.String> fullyQualifiedCheckerNames)
        Returns true if processorString, once transformed into fully-qualified form, is present in fullyQualifiedCheckerNames. Used by SourceChecker to determine whether a class is annotated for any processor that is being run.
        Parameters:
        processorString - the name of a single processor, not a comma-separated list of processors
        fullyQualifiedCheckerNames - a list of fully-qualified checker names
        Returns:
        true if the fully-qualified version of processorString is in fullyQualifiedCheckerNames
      • replaceShorthandProcessor

        protected void replaceShorthandProcessor​(java.util.List<java.lang.String> args)
        For every "-processor" argument in args, replace its immediate successor argument using unabbreviateProcessorNames.
      • unshorthandProcessorNames

        protected static java.lang.String unshorthandProcessorNames​(java.lang.String processorsString,
                                                                    java.util.List<@FullyQualifiedName java.lang.String> fullyQualifiedCheckerNames,
                                                                    boolean allowSubcheckers)
        Takes a string of comma-separated processor names, and expands any shorthands to fully-qualified names from the fullyQualifiedCheckerNames list. For example:
         NullnessChecker → org.checkerframework.checker.nullness.NullnessChecker
         nullness → org.checkerframework.checker.nullness.NullnessChecker
         NullnessChecker,RegexChecker → org.checkerframework.checker.nullness.NullnessChecker,org.checkerframework.checker.regex.RegexChecker
         
        Note, a processor entry only gets replaced if it contains NO "." (i.e., it is not qualified by a package name) and can be found under the package org.checkerframework.checker in checker.jar.
        Parameters:
        processorsString - a comma-separated string identifying processors; often just one processor
        fullyQualifiedCheckerNames - a list of fully-qualified checker names to match processorsString against
        allowSubcheckers - whether to match against fully qualified checker names ending with "Subchecker"
        Returns:
        processorsString where all shorthand references to Checker Framework built-in checkers are replaced with fully-qualified references
      • matchesFullyQualifiedProcessor

        public static boolean matchesFullyQualifiedProcessor​(java.lang.String processorName,
                                                             java.util.List<@FullyQualifiedName java.lang.String> fullyQualifiedCheckerNames,
                                                             boolean allowSubcheckers)
        Given a shorthand processor name, returns true if it can be expanded to a checker in the fullyQualifiedCheckerNames list.
        Parameters:
        processorName - a string identifying one processor
        fullyQualifiedCheckerNames - a list of fully-qualified checker names to match processorName against
        allowSubcheckers - whether to match against fully qualified checker names ending with "Subchecker"
        Returns:
        true if the shorthand processor name can be expanded to a checker in fullyQualifiedCheckerNames