langtools/src/sample/share/javac/processing/src/CheckNamesProcessor.java
author darcy
Thu, 31 Mar 2016 14:56:33 -0700
changeset 36777 28d33fb9097f
parent 25874 83c19f00452c
permissions -rw-r--r--
6818181: Update naming convention annotation processing samples for modules Reviewed-by: jjg
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     1
/*
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
     2
 * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     3
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
     4
 * Redistribution and use in source and binary forms, with or without
06bc494ca11e Initial load
duke
parents:
diff changeset
     5
 * modification, are permitted provided that the following conditions
06bc494ca11e Initial load
duke
parents:
diff changeset
     6
 * are met:
06bc494ca11e Initial load
duke
parents:
diff changeset
     7
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
     8
 *   - Redistributions of source code must retain the above copyright
06bc494ca11e Initial load
duke
parents:
diff changeset
     9
 *     notice, this list of conditions and the following disclaimer.
06bc494ca11e Initial load
duke
parents:
diff changeset
    10
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    11
 *   - Redistributions in binary form must reproduce the above copyright
06bc494ca11e Initial load
duke
parents:
diff changeset
    12
 *     notice, this list of conditions and the following disclaimer in the
06bc494ca11e Initial load
duke
parents:
diff changeset
    13
 *     documentation and/or other materials provided with the distribution.
06bc494ca11e Initial load
duke
parents:
diff changeset
    14
 *
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 10
diff changeset
    15
 *   - Neither the name of Oracle nor the names of its
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    16
 *     contributors may be used to endorse or promote products derived
06bc494ca11e Initial load
duke
parents:
diff changeset
    17
 *     from this software without specific prior written permission.
06bc494ca11e Initial load
duke
parents:
diff changeset
    18
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
06bc494ca11e Initial load
duke
parents:
diff changeset
    20
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
06bc494ca11e Initial load
duke
parents:
diff changeset
    21
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
06bc494ca11e Initial load
duke
parents:
diff changeset
    22
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
06bc494ca11e Initial load
duke
parents:
diff changeset
    23
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
06bc494ca11e Initial load
duke
parents:
diff changeset
    24
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
06bc494ca11e Initial load
duke
parents:
diff changeset
    25
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
06bc494ca11e Initial load
duke
parents:
diff changeset
    26
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
06bc494ca11e Initial load
duke
parents:
diff changeset
    27
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
06bc494ca11e Initial load
duke
parents:
diff changeset
    28
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
06bc494ca11e Initial load
duke
parents:
diff changeset
    29
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
06bc494ca11e Initial load
duke
parents:
diff changeset
    30
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
    31
06bc494ca11e Initial load
duke
parents:
diff changeset
    32
import java.util.Set;
06bc494ca11e Initial load
duke
parents:
diff changeset
    33
import java.util.EnumSet;
06bc494ca11e Initial load
duke
parents:
diff changeset
    34
06bc494ca11e Initial load
duke
parents:
diff changeset
    35
import javax.annotation.processing.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    36
import javax.lang.model.SourceVersion;
06bc494ca11e Initial load
duke
parents:
diff changeset
    37
import javax.lang.model.element.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    38
import javax.lang.model.type.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    39
import javax.lang.model.util.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    40
import static javax.lang.model.SourceVersion.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    41
import static javax.lang.model.element.Modifier.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    42
import static javax.lang.model.element.ElementKind.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    43
import static javax.lang.model.type.TypeKind.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    44
import static javax.lang.model.util.ElementFilter.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    45
import static javax.tools.Diagnostic.Kind.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    46
06bc494ca11e Initial load
duke
parents:
diff changeset
    47
/**
06bc494ca11e Initial load
duke
parents:
diff changeset
    48
 * A sample processor to check naming conventions are being followed.
06bc494ca11e Initial load
duke
parents:
diff changeset
    49
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    50
 * <h3>How to run this processor from the command line</h3>
06bc494ca11e Initial load
duke
parents:
diff changeset
    51
 * <ol>
06bc494ca11e Initial load
duke
parents:
diff changeset
    52
 * <li> Compile this file; for example<br>
06bc494ca11e Initial load
duke
parents:
diff changeset
    53
 *      {@code javac -d procdir CheckNamesProcessor.java}
06bc494ca11e Initial load
duke
parents:
diff changeset
    54
 * <li> Use {@code javac} to run the annotation processor on itself:<br>
06bc494ca11e Initial load
duke
parents:
diff changeset
    55
 *      {@code javac -processorpath procdir -processor CheckNamesProcessor -proc:only CheckNamesProcessor.java}
06bc494ca11e Initial load
duke
parents:
diff changeset
    56
 * </ol>
06bc494ca11e Initial load
duke
parents:
diff changeset
    57
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    58
 * <h3>Another way to run this processor from the command line</h3>
06bc494ca11e Initial load
duke
parents:
diff changeset
    59
 * <ol>
06bc494ca11e Initial load
duke
parents:
diff changeset
    60
 * <li> Compile the processor as before
06bc494ca11e Initial load
duke
parents:
diff changeset
    61
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    62
 * <li> Create a UTF-8 encoded text file named {@code
06bc494ca11e Initial load
duke
parents:
diff changeset
    63
 * javax.annotation.processing.Processor} in the {@code
06bc494ca11e Initial load
duke
parents:
diff changeset
    64
 * META-INF/services} directory.  The contents of the file are a list
06bc494ca11e Initial load
duke
parents:
diff changeset
    65
 * of the binary names of the concrete processor classes, one per
06bc494ca11e Initial load
duke
parents:
diff changeset
    66
 * line.  This provider-configuration file is used by {@linkplain
06bc494ca11e Initial load
duke
parents:
diff changeset
    67
 * java.util.ServiceLoader service-loader} style lookup.
06bc494ca11e Initial load
duke
parents:
diff changeset
    68
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    69
 * <li> Create a {@code jar} file with the processor classes and
06bc494ca11e Initial load
duke
parents:
diff changeset
    70
 * {@code META-INF} information.
06bc494ca11e Initial load
duke
parents:
diff changeset
    71
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    72
 * <li> Such a {@code jar} file can now be used with the <i>discovery
06bc494ca11e Initial load
duke
parents:
diff changeset
    73
 * process</i> without explicitly naming the processor to run:<br>
06bc494ca11e Initial load
duke
parents:
diff changeset
    74
 * {@code javac -processorpath procdir -proc:only CheckNamesProcessor.java}
06bc494ca11e Initial load
duke
parents:
diff changeset
    75
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    76
 * </ol>
06bc494ca11e Initial load
duke
parents:
diff changeset
    77
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    78
 * <h3>Possible Enhancements</h3>
06bc494ca11e Initial load
duke
parents:
diff changeset
    79
 * <ul>
06bc494ca11e Initial load
duke
parents:
diff changeset
    80
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    81
 * <li> Support an annotation processor option to control checking
06bc494ca11e Initial load
duke
parents:
diff changeset
    82
 * exported API elements ({@code public} and {@code protected} ones)
06bc494ca11e Initial load
duke
parents:
diff changeset
    83
 * or all elements
06bc494ca11e Initial load
duke
parents:
diff changeset
    84
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    85
 * <li> Print out warnings that are more informative
06bc494ca11e Initial load
duke
parents:
diff changeset
    86
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    87
 * <li> Return a true/false status if any warnings were printed or
06bc494ca11e Initial load
duke
parents:
diff changeset
    88
 * compute and return name warning count
06bc494ca11e Initial load
duke
parents:
diff changeset
    89
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    90
 * <li> Implement checks of package names
06bc494ca11e Initial load
duke
parents:
diff changeset
    91
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    92
 * <li> Use the Tree API, com.sun.source, to examine names within method bodies
06bc494ca11e Initial load
duke
parents:
diff changeset
    93
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    94
 * <li> Define an annotation type whose presence can indicate a
06bc494ca11e Initial load
duke
parents:
diff changeset
    95
 * different naming convention is being followed
06bc494ca11e Initial load
duke
parents:
diff changeset
    96
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    97
 * <li> Implement customized checks on elements in chosen packages
06bc494ca11e Initial load
duke
parents:
diff changeset
    98
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    99
 * </ul>
06bc494ca11e Initial load
duke
parents:
diff changeset
   100
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
   101
 * @author Joseph D. Darcy
06bc494ca11e Initial load
duke
parents:
diff changeset
   102
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
   103
@SupportedAnnotationTypes("*")     // Process (check) everything
06bc494ca11e Initial load
duke
parents:
diff changeset
   104
public class CheckNamesProcessor extends AbstractProcessor {
06bc494ca11e Initial load
duke
parents:
diff changeset
   105
    private NameChecker nameChecker;
06bc494ca11e Initial load
duke
parents:
diff changeset
   106
06bc494ca11e Initial load
duke
parents:
diff changeset
   107
    /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   108
     * Check that the names of the root elements (and their enclosed
06bc494ca11e Initial load
duke
parents:
diff changeset
   109
     * elements) follow the appropriate naming conventions.  This
06bc494ca11e Initial load
duke
parents:
diff changeset
   110
     * processor examines all files regardless of whether or not
06bc494ca11e Initial load
duke
parents:
diff changeset
   111
     * annotations are present; no new source or class files are
06bc494ca11e Initial load
duke
parents:
diff changeset
   112
     * generated.
06bc494ca11e Initial load
duke
parents:
diff changeset
   113
     *
06bc494ca11e Initial load
duke
parents:
diff changeset
   114
     * <p>Processors that actually process specific annotations should
06bc494ca11e Initial load
duke
parents:
diff changeset
   115
     * <em>not</em> report supporting {@code *}; this could cause
06bc494ca11e Initial load
duke
parents:
diff changeset
   116
     * performance degradations and other undesirable outcomes.
06bc494ca11e Initial load
duke
parents:
diff changeset
   117
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   118
    @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   119
    public boolean process(Set<? extends TypeElement> annotations,
06bc494ca11e Initial load
duke
parents:
diff changeset
   120
            RoundEnvironment roundEnv) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   121
        if (!roundEnv.processingOver()) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   122
            for (Element element : roundEnv.getRootElements() )
06bc494ca11e Initial load
duke
parents:
diff changeset
   123
                nameChecker.checkNames(element);
06bc494ca11e Initial load
duke
parents:
diff changeset
   124
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   125
        return false; // Allow other processors to examine files too.
06bc494ca11e Initial load
duke
parents:
diff changeset
   126
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   127
06bc494ca11e Initial load
duke
parents:
diff changeset
   128
    @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   129
    public void init(ProcessingEnvironment processingEnv) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   130
        super.init(processingEnv);
06bc494ca11e Initial load
duke
parents:
diff changeset
   131
        nameChecker = new NameChecker(processingEnv);
06bc494ca11e Initial load
duke
parents:
diff changeset
   132
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   133
06bc494ca11e Initial load
duke
parents:
diff changeset
   134
    @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   135
    public SourceVersion getSupportedSourceVersion() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   136
        /*
06bc494ca11e Initial load
duke
parents:
diff changeset
   137
         * Return latest source version instead of a fixed version
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   138
         * like RELEASE_9. To return a fixed version, this class could
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   139
         * be annotated with a SupportedSourceVersion annotation.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   140
         *
06bc494ca11e Initial load
duke
parents:
diff changeset
   141
         * Warnings will be issued if any unknown language constructs
06bc494ca11e Initial load
duke
parents:
diff changeset
   142
         * are encountered.
06bc494ca11e Initial load
duke
parents:
diff changeset
   143
         */
06bc494ca11e Initial load
duke
parents:
diff changeset
   144
        return SourceVersion.latest();
06bc494ca11e Initial load
duke
parents:
diff changeset
   145
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   146
06bc494ca11e Initial load
duke
parents:
diff changeset
   147
    /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   148
     * Provide checks that an element and its enclosed elements follow
06bc494ca11e Initial load
duke
parents:
diff changeset
   149
     * the usual naming conventions.
06bc494ca11e Initial load
duke
parents:
diff changeset
   150
     *
9303
eae35c201e19 7032975: API files in javax.annotation.processing need to be updated for references to JLS
jjh
parents: 7681
diff changeset
   151
     * <p> Conventions from section 6.8 of
eae35c201e19 7032975: API files in javax.annotation.processing need to be updated for references to JLS
jjh
parents: 7681
diff changeset
   152
     *     <cite>The Java&trade; Language Specification</cite>
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   153
     *
06bc494ca11e Initial load
duke
parents:
diff changeset
   154
     * <ul>
06bc494ca11e Initial load
duke
parents:
diff changeset
   155
     * <li> Classes and interfaces: camel case, first letter is uppercase
06bc494ca11e Initial load
duke
parents:
diff changeset
   156
     * <li> Methods: camel case, first letter is lowercase
06bc494ca11e Initial load
duke
parents:
diff changeset
   157
     * <li> Type variables: one uppercase letter
06bc494ca11e Initial load
duke
parents:
diff changeset
   158
     * <li> Fields
06bc494ca11e Initial load
duke
parents:
diff changeset
   159
     * <ul>
06bc494ca11e Initial load
duke
parents:
diff changeset
   160
     * <li> non-final: camel case, initial lowercase
06bc494ca11e Initial load
duke
parents:
diff changeset
   161
     * <li> constant: uppercase separated by underscores
06bc494ca11e Initial load
duke
parents:
diff changeset
   162
     * </ul>
9303
eae35c201e19 7032975: API files in javax.annotation.processing need to be updated for references to JLS
jjh
parents: 7681
diff changeset
   163
     * <li> Packages: checks left as exercise for the reader, see section 7.7 of
eae35c201e19 7032975: API files in javax.annotation.processing need to be updated for references to JLS
jjh
parents: 7681
diff changeset
   164
     * <cite>The Java&trade; Language Specification</cite>.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   165
     * </ul>
06bc494ca11e Initial load
duke
parents:
diff changeset
   166
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   167
    private static class NameChecker {
06bc494ca11e Initial load
duke
parents:
diff changeset
   168
        private final Messager messager;
06bc494ca11e Initial load
duke
parents:
diff changeset
   169
        private final Types typeUtils;
06bc494ca11e Initial load
duke
parents:
diff changeset
   170
06bc494ca11e Initial load
duke
parents:
diff changeset
   171
        NameCheckScanner nameCheckScanner = new NameCheckScanner();
06bc494ca11e Initial load
duke
parents:
diff changeset
   172
06bc494ca11e Initial load
duke
parents:
diff changeset
   173
        NameChecker(ProcessingEnvironment processsingEnv) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   174
            this.messager  = processsingEnv.getMessager();
06bc494ca11e Initial load
duke
parents:
diff changeset
   175
            this.typeUtils = processsingEnv.getTypeUtils();
06bc494ca11e Initial load
duke
parents:
diff changeset
   176
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   177
06bc494ca11e Initial load
duke
parents:
diff changeset
   178
        /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   179
         * If the name of the argument or its enclosed elements
06bc494ca11e Initial load
duke
parents:
diff changeset
   180
         * violates the naming conventions, report a warning.
06bc494ca11e Initial load
duke
parents:
diff changeset
   181
         */
06bc494ca11e Initial load
duke
parents:
diff changeset
   182
        public void checkNames(Element element) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   183
            // Implement name checks with a visitor, but expose that
06bc494ca11e Initial load
duke
parents:
diff changeset
   184
            // functionality through this method instead.
06bc494ca11e Initial load
duke
parents:
diff changeset
   185
            nameCheckScanner.scan(element);
06bc494ca11e Initial load
duke
parents:
diff changeset
   186
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   187
06bc494ca11e Initial load
duke
parents:
diff changeset
   188
        /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   189
         * Visitor to implement name checks.
06bc494ca11e Initial load
duke
parents:
diff changeset
   190
         */
25690
b1dac768ab79 8050430: Provided new utility visitors supporting SourceVersion.RELEASE_9
darcy
parents: 10192
diff changeset
   191
        private class NameCheckScanner extends ElementScanner9<Void, Void> {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   192
            // The visitor could be enhanced to return true/false if
06bc494ca11e Initial load
duke
parents:
diff changeset
   193
            // there were warnings reported or a count of the number
06bc494ca11e Initial load
duke
parents:
diff changeset
   194
            // of warnings.  This could be facilitated by using
06bc494ca11e Initial load
duke
parents:
diff changeset
   195
            // Boolean or Integer instead of Void for the actual type
06bc494ca11e Initial load
duke
parents:
diff changeset
   196
            // arguments.  In more detail, one way to tally the number
06bc494ca11e Initial load
duke
parents:
diff changeset
   197
            // of warnings would be for each method to return the sum
06bc494ca11e Initial load
duke
parents:
diff changeset
   198
            // of the warnings it and the methods it called issued, a
06bc494ca11e Initial load
duke
parents:
diff changeset
   199
            // bottom-up computation.  In that case, the first type
06bc494ca11e Initial load
duke
parents:
diff changeset
   200
            // argument would be Integer and the second type argument
06bc494ca11e Initial load
duke
parents:
diff changeset
   201
            // would still be Void.  Alternatively, the current count
06bc494ca11e Initial load
duke
parents:
diff changeset
   202
            // could be passed along in Integer parameter p and each
06bc494ca11e Initial load
duke
parents:
diff changeset
   203
            // method could return the Integer sum of p and the
06bc494ca11e Initial load
duke
parents:
diff changeset
   204
            // warnings the method issued.  Some computations are more
06bc494ca11e Initial load
duke
parents:
diff changeset
   205
            // naturally expressed in one form instead of the other.
06bc494ca11e Initial load
duke
parents:
diff changeset
   206
            // If greater control is needed over traversal order, a
06bc494ca11e Initial load
duke
parents:
diff changeset
   207
            // SimpleElementVisitor can be extended instead of an
06bc494ca11e Initial load
duke
parents:
diff changeset
   208
            // ElementScanner.
06bc494ca11e Initial load
duke
parents:
diff changeset
   209
06bc494ca11e Initial load
duke
parents:
diff changeset
   210
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   211
             * Check the name of a type and its enclosed elements and
06bc494ca11e Initial load
duke
parents:
diff changeset
   212
             * type parameters.
06bc494ca11e Initial load
duke
parents:
diff changeset
   213
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   214
            @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   215
            public Void visitType(TypeElement e, Void p) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   216
                scan(e.getTypeParameters(), p); // Check the names of any type parameters
06bc494ca11e Initial load
duke
parents:
diff changeset
   217
                checkCamelCase(e, true);        // Check the name of the class or interface
06bc494ca11e Initial load
duke
parents:
diff changeset
   218
                super.visitType(e, p);          // Check the names of any enclosed elements
06bc494ca11e Initial load
duke
parents:
diff changeset
   219
                return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   220
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   221
06bc494ca11e Initial load
duke
parents:
diff changeset
   222
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   223
             * Check the name of an executable (method, constructor,
06bc494ca11e Initial load
duke
parents:
diff changeset
   224
             * etc.) and its type parameters.
06bc494ca11e Initial load
duke
parents:
diff changeset
   225
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   226
            @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   227
            public Void visitExecutable(ExecutableElement e, Void p) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   228
                scan(e.getTypeParameters(), p); // Check the names of any type parameters
06bc494ca11e Initial load
duke
parents:
diff changeset
   229
06bc494ca11e Initial load
duke
parents:
diff changeset
   230
                // Check the name of the executable
06bc494ca11e Initial load
duke
parents:
diff changeset
   231
                if (e.getKind() == METHOD) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   232
                    // Make sure that a method does not have the same
06bc494ca11e Initial load
duke
parents:
diff changeset
   233
                    // name as its class or interface.
06bc494ca11e Initial load
duke
parents:
diff changeset
   234
                    Name name = e.getSimpleName();
06bc494ca11e Initial load
duke
parents:
diff changeset
   235
                    if (name.contentEquals(e.getEnclosingElement().getSimpleName()))
06bc494ca11e Initial load
duke
parents:
diff changeset
   236
                        messager.printMessage(WARNING,
06bc494ca11e Initial load
duke
parents:
diff changeset
   237
                                              "A method should not have the same name as its enclosing type, ``" +
06bc494ca11e Initial load
duke
parents:
diff changeset
   238
                                              name + "''." , e);
06bc494ca11e Initial load
duke
parents:
diff changeset
   239
                    checkCamelCase(e, false);
06bc494ca11e Initial load
duke
parents:
diff changeset
   240
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   241
                // else constructors and initializers don't have user-defined names
06bc494ca11e Initial load
duke
parents:
diff changeset
   242
06bc494ca11e Initial load
duke
parents:
diff changeset
   243
                // At this point, could use the Tree API,
06bc494ca11e Initial load
duke
parents:
diff changeset
   244
                // com.sun.source, to examine the names of entities
06bc494ca11e Initial load
duke
parents:
diff changeset
   245
                // inside a method.
06bc494ca11e Initial load
duke
parents:
diff changeset
   246
                super.visitExecutable(e, p);
06bc494ca11e Initial load
duke
parents:
diff changeset
   247
                return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   248
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   249
06bc494ca11e Initial load
duke
parents:
diff changeset
   250
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   251
             * Check the name of a field, parameter, etc.
06bc494ca11e Initial load
duke
parents:
diff changeset
   252
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   253
            @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   254
            public Void visitVariable(VariableElement e, Void p) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   255
                if (!checkForSerial(e)) { // serialVersionUID checks
06bc494ca11e Initial load
duke
parents:
diff changeset
   256
                    // Is the variable a constant?
06bc494ca11e Initial load
duke
parents:
diff changeset
   257
                    if (e.getKind() == ENUM_CONSTANT ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   258
                        e.getConstantValue() != null ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   259
                        heuristicallyConstant(e) )
06bc494ca11e Initial load
duke
parents:
diff changeset
   260
                        checkAllCaps(e); // includes enum constants
06bc494ca11e Initial load
duke
parents:
diff changeset
   261
                    else
06bc494ca11e Initial load
duke
parents:
diff changeset
   262
                        checkCamelCase(e, false);
06bc494ca11e Initial load
duke
parents:
diff changeset
   263
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   264
                // A call to super can be elided with the current language definition.
06bc494ca11e Initial load
duke
parents:
diff changeset
   265
                // super.visitVariable(e, p);
06bc494ca11e Initial load
duke
parents:
diff changeset
   266
                return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   267
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   268
06bc494ca11e Initial load
duke
parents:
diff changeset
   269
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   270
             * Check the name of a type parameter.
06bc494ca11e Initial load
duke
parents:
diff changeset
   271
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   272
            @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   273
            public Void visitTypeParameter(TypeParameterElement e, Void p) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   274
                checkAllCaps(e);
06bc494ca11e Initial load
duke
parents:
diff changeset
   275
                // A call to super can be elided with the current language definition.
06bc494ca11e Initial load
duke
parents:
diff changeset
   276
                // super.visitTypeParameter(e, p);
06bc494ca11e Initial load
duke
parents:
diff changeset
   277
                return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   278
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   279
06bc494ca11e Initial load
duke
parents:
diff changeset
   280
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   281
             * Check the name of a package.
06bc494ca11e Initial load
duke
parents:
diff changeset
   282
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   283
            @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   284
            public Void visitPackage(PackageElement e, Void p) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   285
                /*
06bc494ca11e Initial load
duke
parents:
diff changeset
   286
                 * Implementing the checks of package names is left
9303
eae35c201e19 7032975: API files in javax.annotation.processing need to be updated for references to JLS
jjh
parents: 7681
diff changeset
   287
                 * as an exercise for the reader, see JLS section
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   288
                 * 7.7 for conventions.
06bc494ca11e Initial load
duke
parents:
diff changeset
   289
                 */
06bc494ca11e Initial load
duke
parents:
diff changeset
   290
06bc494ca11e Initial load
duke
parents:
diff changeset
   291
                // Whether or not this method should call
06bc494ca11e Initial load
duke
parents:
diff changeset
   292
                // super.visitPackage, to visit the packages enclosed
06bc494ca11e Initial load
duke
parents:
diff changeset
   293
                // elements, is a design decision based on what a
06bc494ca11e Initial load
duke
parents:
diff changeset
   294
                // PackageElemement is used to mean in this context.
06bc494ca11e Initial load
duke
parents:
diff changeset
   295
                // A PackageElement can represent a whole package, so
06bc494ca11e Initial load
duke
parents:
diff changeset
   296
                // it can provide a concise way to indicate many
06bc494ca11e Initial load
duke
parents:
diff changeset
   297
                // user-defined types should be visited.  However, a
06bc494ca11e Initial load
duke
parents:
diff changeset
   298
                // PackageElement can also represent a
06bc494ca11e Initial load
duke
parents:
diff changeset
   299
                // package-info.java file, as would be in the case if
06bc494ca11e Initial load
duke
parents:
diff changeset
   300
                // the PackageElement came from
06bc494ca11e Initial load
duke
parents:
diff changeset
   301
                // RoundEnvironment.getRootElements.  In that case,
06bc494ca11e Initial load
duke
parents:
diff changeset
   302
                // the package-info file and other files in that
06bc494ca11e Initial load
duke
parents:
diff changeset
   303
                // package could be passed in.  Therefore, without
06bc494ca11e Initial load
duke
parents:
diff changeset
   304
                // further checks, types in a package could be visited
06bc494ca11e Initial load
duke
parents:
diff changeset
   305
                // more than once if a package's elements were visited
06bc494ca11e Initial load
duke
parents:
diff changeset
   306
                // too.
06bc494ca11e Initial load
duke
parents:
diff changeset
   307
                return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   308
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   309
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   310
            /**
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   311
             * Check the name of a module.
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   312
             */
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   313
            @Override
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   314
            public Void visitModule(ModuleElement e, Void p) {
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   315
                /*
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   316
                 * Implementing the checks of package names is left as
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   317
                 * an exercise for the reader.
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   318
                 */
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   319
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   320
                // Similar to the options of how visiting a package
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   321
                // could be handled, whether or not this method should
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   322
                // call super and scan, etc. is a design choice on
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   323
                // whether it is desired for a ModuleElement to
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   324
                // represent a module-info file or for the
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   325
                // ModuleElement to represent the entire contents of a
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   326
                // module, including its packages.
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   327
                return null;
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   328
            }
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   329
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   330
            @Override
06bc494ca11e Initial load
duke
parents:
diff changeset
   331
            public Void visitUnknown(Element e, Void p) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   332
                // This method will be called if a kind of element
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   333
                // added after JDK 9 is visited.  Since as of this
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   334
                // writing the conventions for such constructs aren't
06bc494ca11e Initial load
duke
parents:
diff changeset
   335
                // known, issue a warning.
06bc494ca11e Initial load
duke
parents:
diff changeset
   336
                messager.printMessage(WARNING,
06bc494ca11e Initial load
duke
parents:
diff changeset
   337
                                      "Unknown kind of element, " + e.getKind() +
06bc494ca11e Initial load
duke
parents:
diff changeset
   338
                                      ", no name checking performed.", e);
06bc494ca11e Initial load
duke
parents:
diff changeset
   339
                return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   340
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   341
06bc494ca11e Initial load
duke
parents:
diff changeset
   342
            // All the name checking methods assume the examined names
06bc494ca11e Initial load
duke
parents:
diff changeset
   343
            // are syntactically well-formed identifiers.
06bc494ca11e Initial load
duke
parents:
diff changeset
   344
06bc494ca11e Initial load
duke
parents:
diff changeset
   345
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   346
             * Return {@code true} if this variable is a field named
06bc494ca11e Initial load
duke
parents:
diff changeset
   347
             * "serialVersionUID"; false otherwise.  A true
06bc494ca11e Initial load
duke
parents:
diff changeset
   348
             * serialVersionUID of a class has type {@code long} and
06bc494ca11e Initial load
duke
parents:
diff changeset
   349
             * is static and final.
06bc494ca11e Initial load
duke
parents:
diff changeset
   350
             *
06bc494ca11e Initial load
duke
parents:
diff changeset
   351
             * <p>To check that a Serializable class defines a proper
06bc494ca11e Initial load
duke
parents:
diff changeset
   352
             * serialVersionUID, run javac with -Xlint:serial.
06bc494ca11e Initial load
duke
parents:
diff changeset
   353
             *
06bc494ca11e Initial load
duke
parents:
diff changeset
   354
             * @return true if this variable is a serialVersionUID field and false otherwise
06bc494ca11e Initial load
duke
parents:
diff changeset
   355
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   356
            private boolean checkForSerial(VariableElement e) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   357
                // If a field is named "serialVersionUID" ...
06bc494ca11e Initial load
duke
parents:
diff changeset
   358
                if (e.getKind() == FIELD &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   359
                    e.getSimpleName().contentEquals("serialVersionUID")) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   360
                    // ... issue a warning if it does not act as a serialVersionUID
06bc494ca11e Initial load
duke
parents:
diff changeset
   361
                    if (!(e.getModifiers().containsAll(EnumSet.of(STATIC, FINAL)) &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   362
                            typeUtils.isSameType(e.asType(), typeUtils.getPrimitiveType(LONG)) &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   363
                            e.getEnclosingElement().getKind() == CLASS )) // could check that class implements Serializable
06bc494ca11e Initial load
duke
parents:
diff changeset
   364
                        messager.printMessage(WARNING,
06bc494ca11e Initial load
duke
parents:
diff changeset
   365
                                              "Field named ``serialVersionUID'' is not acting as such.", e);
06bc494ca11e Initial load
duke
parents:
diff changeset
   366
                    return true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   367
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   368
                return false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   369
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   370
06bc494ca11e Initial load
duke
parents:
diff changeset
   371
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   372
             * Using heuristics, return {@code true} is the variable
06bc494ca11e Initial load
duke
parents:
diff changeset
   373
             * should follow the naming conventions for constants and
06bc494ca11e Initial load
duke
parents:
diff changeset
   374
             * {@code false} otherwise.  For example, the public
06bc494ca11e Initial load
duke
parents:
diff changeset
   375
             * static final fields ZERO, ONE, and TEN in
06bc494ca11e Initial load
duke
parents:
diff changeset
   376
             * java.math.BigDecimal are logically constants (and named
06bc494ca11e Initial load
duke
parents:
diff changeset
   377
             * as constants) even though BigDecimal values are not
06bc494ca11e Initial load
duke
parents:
diff changeset
   378
             * regarded as constants by the language specification.
06bc494ca11e Initial load
duke
parents:
diff changeset
   379
             * However, some final fields may not act as constants
06bc494ca11e Initial load
duke
parents:
diff changeset
   380
             * since the field may be a reference to a mutable object.
06bc494ca11e Initial load
duke
parents:
diff changeset
   381
             *
06bc494ca11e Initial load
duke
parents:
diff changeset
   382
             * <p> These heuristics could be tweaked to provide better
06bc494ca11e Initial load
duke
parents:
diff changeset
   383
             * fidelity.
06bc494ca11e Initial load
duke
parents:
diff changeset
   384
             *
06bc494ca11e Initial load
duke
parents:
diff changeset
   385
             * @return true if the current heuristics regard the
06bc494ca11e Initial load
duke
parents:
diff changeset
   386
             * variable as a constant and false otherwise.
06bc494ca11e Initial load
duke
parents:
diff changeset
   387
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   388
            private boolean heuristicallyConstant(VariableElement e) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   389
                // Fields declared in interfaces are logically
06bc494ca11e Initial load
duke
parents:
diff changeset
   390
                // constants, JLSv3 section 9.3.
06bc494ca11e Initial load
duke
parents:
diff changeset
   391
                if (e.getEnclosingElement().getKind() == INTERFACE)
06bc494ca11e Initial load
duke
parents:
diff changeset
   392
                    return true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   393
                else if (e.getKind() == FIELD &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   394
                         e.getModifiers().containsAll(EnumSet.of(PUBLIC, STATIC, FINAL)))
06bc494ca11e Initial load
duke
parents:
diff changeset
   395
                    return true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   396
                else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   397
                    // A parameter declared final should not be named like
06bc494ca11e Initial load
duke
parents:
diff changeset
   398
                    // a constant, neither should exception parameters.
06bc494ca11e Initial load
duke
parents:
diff changeset
   399
                    return false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   400
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   401
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   402
06bc494ca11e Initial load
duke
parents:
diff changeset
   403
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   404
             * Print a warning if an element's simple name is not in
06bc494ca11e Initial load
duke
parents:
diff changeset
   405
             * camel case.  If there are two adjacent uppercase
06bc494ca11e Initial load
duke
parents:
diff changeset
   406
             * characters, the name is considered to violate the
06bc494ca11e Initial load
duke
parents:
diff changeset
   407
             * camel case naming convention.
06bc494ca11e Initial load
duke
parents:
diff changeset
   408
             *
06bc494ca11e Initial load
duke
parents:
diff changeset
   409
             * @param e the element whose name will be checked
06bc494ca11e Initial load
duke
parents:
diff changeset
   410
             * @param initialCaps whether or not the first character should be uppercase
06bc494ca11e Initial load
duke
parents:
diff changeset
   411
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   412
            private void checkCamelCase(Element e, boolean initialCaps) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   413
                String name = e.getSimpleName().toString();
06bc494ca11e Initial load
duke
parents:
diff changeset
   414
                boolean previousUpper = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   415
                boolean conventional = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   416
                int firstCodePoint = name.codePointAt(0);
06bc494ca11e Initial load
duke
parents:
diff changeset
   417
06bc494ca11e Initial load
duke
parents:
diff changeset
   418
                if (Character.isUpperCase(firstCodePoint)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   419
                    previousUpper = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   420
                    if (!initialCaps) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   421
                        messager.printMessage(WARNING,
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   422
                                              "Name ``" + name + "'' should start in lowercase.", e);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   423
                        return;
06bc494ca11e Initial load
duke
parents:
diff changeset
   424
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   425
                } else if (Character.isLowerCase(firstCodePoint)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   426
                    if (initialCaps) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   427
                        messager.printMessage(WARNING,
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   428
                                              "Name ``" + name + "'' should start in uppercase.", e);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   429
                        return;
06bc494ca11e Initial load
duke
parents:
diff changeset
   430
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   431
                } else // underscore, etc.
06bc494ca11e Initial load
duke
parents:
diff changeset
   432
                    conventional = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   433
06bc494ca11e Initial load
duke
parents:
diff changeset
   434
                if (conventional) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   435
                    int cp = firstCodePoint;
06bc494ca11e Initial load
duke
parents:
diff changeset
   436
                    for (int i = Character.charCount(cp);
06bc494ca11e Initial load
duke
parents:
diff changeset
   437
                         i < name.length();
06bc494ca11e Initial load
duke
parents:
diff changeset
   438
                         i += Character.charCount(cp)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   439
                        cp = name.codePointAt(i);
06bc494ca11e Initial load
duke
parents:
diff changeset
   440
                        if (Character.isUpperCase(cp)){
06bc494ca11e Initial load
duke
parents:
diff changeset
   441
                            if (previousUpper) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   442
                                conventional = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   443
                                break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   444
                            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   445
                            previousUpper = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   446
                        } else
06bc494ca11e Initial load
duke
parents:
diff changeset
   447
                            previousUpper = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   448
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   449
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   450
06bc494ca11e Initial load
duke
parents:
diff changeset
   451
                if (!conventional)
06bc494ca11e Initial load
duke
parents:
diff changeset
   452
                    messager.printMessage(WARNING,
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   453
                                          "Name ``" + name + "'', should be in camel case.", e);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   454
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   455
06bc494ca11e Initial load
duke
parents:
diff changeset
   456
            /**
06bc494ca11e Initial load
duke
parents:
diff changeset
   457
             * Print a warning if the element's name is not a sequence
06bc494ca11e Initial load
duke
parents:
diff changeset
   458
             * of uppercase letters separated by underscores ("_").
06bc494ca11e Initial load
duke
parents:
diff changeset
   459
             *
06bc494ca11e Initial load
duke
parents:
diff changeset
   460
             * @param e the element whose name will be checked
06bc494ca11e Initial load
duke
parents:
diff changeset
   461
             */
06bc494ca11e Initial load
duke
parents:
diff changeset
   462
            private void checkAllCaps(Element e) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   463
                String name = e.getSimpleName().toString();
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   464
                /*
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   465
                 * Traditionally type variables are recommended to
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   466
                 * have one-character names. As an exercise for the
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   467
                 * reader, a more nuanced policy can be implemented.
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   468
                 */
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   469
                if (e.getKind() == TYPE_PARAMETER) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   470
                    if (name.codePointCount(0, name.length()) > 1 ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   471
                        // Assume names are non-empty
06bc494ca11e Initial load
duke
parents:
diff changeset
   472
                        !Character.isUpperCase(name.codePointAt(0)))
06bc494ca11e Initial load
duke
parents:
diff changeset
   473
                        messager.printMessage(WARNING,
06bc494ca11e Initial load
duke
parents:
diff changeset
   474
                                              "A type variable's name,``" + name +
06bc494ca11e Initial load
duke
parents:
diff changeset
   475
                                              "'', should be a single uppercace character.",
06bc494ca11e Initial load
duke
parents:
diff changeset
   476
                                              e);
06bc494ca11e Initial load
duke
parents:
diff changeset
   477
                } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   478
                    boolean conventional = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   479
                    int firstCodePoint = name.codePointAt(0);
06bc494ca11e Initial load
duke
parents:
diff changeset
   480
06bc494ca11e Initial load
duke
parents:
diff changeset
   481
                    // Starting with an underscore is not conventional
06bc494ca11e Initial load
duke
parents:
diff changeset
   482
                    if (!Character.isUpperCase(firstCodePoint))
06bc494ca11e Initial load
duke
parents:
diff changeset
   483
                        conventional = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   484
                    else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   485
                        // Was the previous character an underscore?
06bc494ca11e Initial load
duke
parents:
diff changeset
   486
                        boolean previousUnderscore = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   487
                        int cp = firstCodePoint;
06bc494ca11e Initial load
duke
parents:
diff changeset
   488
                        for (int i = Character.charCount(cp);
06bc494ca11e Initial load
duke
parents:
diff changeset
   489
                             i < name.length();
06bc494ca11e Initial load
duke
parents:
diff changeset
   490
                             i += Character.charCount(cp)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   491
                            cp = name.codePointAt(i);
06bc494ca11e Initial load
duke
parents:
diff changeset
   492
                            if (cp == (int) '_') {
06bc494ca11e Initial load
duke
parents:
diff changeset
   493
                                if (previousUnderscore) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   494
                                    conventional = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   495
                                    break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   496
                                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   497
                                previousUnderscore = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   498
                            } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   499
                                previousUnderscore = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   500
                                if (!Character.isUpperCase(cp) && !Character.isDigit(cp) ) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   501
                                    conventional = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   502
                                    break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   503
                                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   504
                            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   505
                        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   506
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   507
06bc494ca11e Initial load
duke
parents:
diff changeset
   508
                    if (!conventional)
06bc494ca11e Initial load
duke
parents:
diff changeset
   509
                        messager.printMessage(WARNING,
06bc494ca11e Initial load
duke
parents:
diff changeset
   510
                                              "A constant's name, ``" + name + "'', should be ALL_CAPS.",
06bc494ca11e Initial load
duke
parents:
diff changeset
   511
                                              e);
06bc494ca11e Initial load
duke
parents:
diff changeset
   512
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   513
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   514
06bc494ca11e Initial load
duke
parents:
diff changeset
   515
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   516
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   517
}
06bc494ca11e Initial load
duke
parents:
diff changeset
   518
06bc494ca11e Initial load
duke
parents:
diff changeset
   519
/**
06bc494ca11e Initial load
duke
parents:
diff changeset
   520
 * Lots of bad names.  Don't write code like this!
36777
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   521
 *
28d33fb9097f 6818181: Update naming convention annotation processing samples for modules
darcy
parents: 25874
diff changeset
   522
 * The unmodified name checks will print 11 warnings for this class.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   523
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
   524
class BADLY_NAMED_CODE {
06bc494ca11e Initial load
duke
parents:
diff changeset
   525
    enum colors {
06bc494ca11e Initial load
duke
parents:
diff changeset
   526
        red,
06bc494ca11e Initial load
duke
parents:
diff changeset
   527
        blue,
06bc494ca11e Initial load
duke
parents:
diff changeset
   528
        green;
06bc494ca11e Initial load
duke
parents:
diff changeset
   529
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   530
06bc494ca11e Initial load
duke
parents:
diff changeset
   531
    // Don't start the name of a constant with an underscore
06bc494ca11e Initial load
duke
parents:
diff changeset
   532
    static final int _FORTY_TWO = 42;
06bc494ca11e Initial load
duke
parents:
diff changeset
   533
06bc494ca11e Initial load
duke
parents:
diff changeset
   534
    // Non-constants shouldn't use ALL_CAPS
06bc494ca11e Initial load
duke
parents:
diff changeset
   535
    public static int NOT_A_CONSTANT = _FORTY_TWO;
06bc494ca11e Initial load
duke
parents:
diff changeset
   536
06bc494ca11e Initial load
duke
parents:
diff changeset
   537
    // *Not* a serialVersionUID
06bc494ca11e Initial load
duke
parents:
diff changeset
   538
    private static final int serialVersionUID = _FORTY_TWO;
06bc494ca11e Initial load
duke
parents:
diff changeset
   539
06bc494ca11e Initial load
duke
parents:
diff changeset
   540
    // Not a constructor
06bc494ca11e Initial load
duke
parents:
diff changeset
   541
    protected void BADLY_NAMED_CODE() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   542
        return;
06bc494ca11e Initial load
duke
parents:
diff changeset
   543
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   544
06bc494ca11e Initial load
duke
parents:
diff changeset
   545
    public void NOTcamelCASEmethodNAME() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   546
        return;
06bc494ca11e Initial load
duke
parents:
diff changeset
   547
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   548
}