Diagnostics Examples.

The "examples/ directory contains a collection of examples of Java code, each of
which is designed to illustrate one or more diagnostics that can be generated by
the JDK Java compiler, javac. These examples are represented by files or
directories of files, each of which is designed to illustrate a specific
diagnostic. Sometimes it is unavoidable that creating one issue will lead to
downstream issues: this is especially true for lex errors, where the error
recovery is fragile at best. Each example declares the diagnostics that it is
expected to generate -- this allows the examples to be verified and facilitates
searching for examples for specific messages.

Normally, tests for javac errors avoid checking the actual error messages that
get generated. Older tests simply verify that one or more warnings or errors
are generated; more recent tests verify that specific messages are generated,
but these tests typically avoid checking the localized text by using the
-XDrawDiagnostics mechanism. In addition, the focus of such tests is often on
completeness instead of simplicity.

By contrast, the intent of these examples is to provide simple and easy to
understand examples of the situations in which a diagnostic can arise, and the
messages that may be displayed. This will aid in reviewing the output generated
by javac and in localizing the resource bundle to other locales. In addition,
the examples include simple meta-information so that the collection as a whole
can be audited for coverage, thus encouraging new examples to be added when new
diagnostics are added to javac.

There are two utilities for processing these examples.

The first utility is "CheckExamples" which checks various conditions for the
examples:
-- each example must generate exactly the set of keys that it is declared to
   generate
-- together, the examples must generate all the resource keys coming from javac
   (except for resource keys that are registered in a "not yet" list)
-- the "not yet" list should only contain those resource keys from javac that
   are not covered by any example

CheckExamples can be run standalone, and as a jtreg test, and will fail if any
anomalous conditions are found.

The second utility is "RunExamples" which runs selected examples or all of them.
The examples can be run with -XDrawDiagnostics or without.   Examples can be
selected by name or by resource key.   Most examples are simple to run directly
anyway, but some use annotation processors or sourcepath or other options, and
the framework handles all these requirements.

RunExamples can be run standalone and as a jtreg test, in which case it
generates a simple plain text report. In addition, the langtools/make/build.xml
file has a target "diags-examples" that uses RunExamples to create an HTML
report containing the output from all the examples.


Adding examples.

When new diagnostics are added to javac, CheckExamples will probably initially
fail because the diagnostic will not have a corresponding example, nor will the
resource key be registered in the "not yet" list. Avoid the temptation to
simply add the resource key to the "not yet" list, except as a last resort.

Examples should be as simple as possible to illustrate a diagnostic.  An example
that is a single file is to be preferred over multiple files. An example that
generates just the one intended diagnostic is to be preferred over one that
generates multiple diagnostics. Examples should be a simple illustration of the
conditions that give rise to the diagnostic and should be easy to understand by
the reviewer and, potentially, by the localization folk, who have to understand
the context in which these new messages can appear.


Specification for writing examples.

An example may a single file or a directory of files directly in the "examples"
directory. One file within an example must contain meta-information such as the
keys that it generates, any javac options that may be required, and additional
info about how to run the test, if needed.

If an example is represented by a directory of files, by default all files
within that directory will be compiled together, putting all the files on the
command line. However, some subdirectories are special:
-- processors/
    Files within this directory will be treated as annotation processors and
    compiled ahead of time. Currently, annotation processors are made available
    to javac using the -classpath option (not -processorpath). This is to avoid
    explicit use of annotation processing options on the javac command line.
    Any annotation processors found will be registered for access by the JDK
    service loaded. Currently, annotation processors are assumed to be in the
    unnamed package.
-- sourcepath/
    If present, this directory will be put passed to javac using the -sourcepath
    option.
-- classpath/
    This name is reserved for future use. It is expected that this directory
    will be used to provide classes to be compiled and passes to javac via the
    -classpath option.
-- support/
    This name is reserved for future use. It is expected that this directory
    will be used to provide classes that setup non-standard conditions for a
    test, such as very large source files, or illegal class files.

Meta-information is represented by simple comment lines in exactly one of the
source files of the example.  The file must not be in one of the special
subdirectories (processors/, sourcepath/, classpath/ or support/). Three
different types of information may be given:
// key: <resource-key>
    One or more such lines must be provided, declaring the full resource keys
    that will be used by javac when this example is run.
// options: <javac-options>
    This line may be given at most once, providing one or more options to be
    passed to javac. It is not possible to use this to specify options that
    require filenames or directories.
// run: <mode> <optional-args>
    This line may be given at most once, providing infomation about how to
    run the example. Three different kinds are supported:
    jsr199 -- The example will be run using the JSR 199 Compiler API.
              This is the default if the tag is omitted. Messages generated
              by the "rich diagnostic formatter" can not be accessed in this
              way.  However, this mode does provide additional options for
              simulating errors in the filesystem. (See the options below.)
    simple -- The example will be run using the simple com.sun.tools.javac.Main
              API. This mode is most like the normal command line invocation.
    backdoor -- The example will be run using an internal "backdoor" API, that
              interposes access to the main compiler message bundle. This mode
              is required to detect and track messages that bypass the normal
              diagnostic mechanisms, such as output generated by the -verbose
              option.
    exec -- The example will be run in a subprocess. This mode is useful when
              the example will leave files open, such that the only way to close
              them is to exit the process.

The "jsr199" run mode accepts the following options:
    -cantRead:pattern
    -cantWrite:pattern
In both cases, the pattern is a standard Java regular expression (See the
javadoc for java.util.regex.Pattern for a complete specification.) Attempts to
read or write from files matching the corresponding pattern will cause an
IOException to occur within javac.

