Coverage Report - com.puppycrawl.tools.checkstyle.utils.TokenUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
TokenUtils
100%
50/50
100%
20/20
0
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2017 the original author or authors.
 4  
 //
 5  
 // This library is free software; you can redistribute it and/or
 6  
 // modify it under the terms of the GNU Lesser General Public
 7  
 // License as published by the Free Software Foundation; either
 8  
 // version 2.1 of the License, or (at your option) any later version.
 9  
 //
 10  
 // This library is distributed in the hope that it will be useful,
 11  
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 // Lesser General Public License for more details.
 14  
 //
 15  
 // You should have received a copy of the GNU Lesser General Public
 16  
 // License along with this library; if not, write to the Free Software
 17  
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  
 ////////////////////////////////////////////////////////////////////////////////
 19  
 
 20  
 package com.puppycrawl.tools.checkstyle.utils;
 21  
 
 22  
 import java.lang.reflect.Field;
 23  
 import java.util.Locale;
 24  
 import java.util.Optional;
 25  
 import java.util.ResourceBundle;
 26  
 import java.util.function.Predicate;
 27  
 
 28  
 import com.google.common.collect.ImmutableMap;
 29  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 30  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 31  
 
 32  
 /**
 33  
  * Contains utility methods for tokens.
 34  
  *
 35  
  * @author <a href="mailto:nesterenko-aleksey@list.ru">Aleksey Nesterenko</a>
 36  
  */
 37  
 public final class TokenUtils {
 38  
 
 39  
     /** Maps from a token name to value. */
 40  
     private static final ImmutableMap<String, Integer> TOKEN_NAME_TO_VALUE;
 41  
     /** Maps from a token value to name. */
 42  
     private static final String[] TOKEN_VALUE_TO_NAME;
 43  
 
 44  
     /** Array of all token IDs. */
 45  
     private static final int[] TOKEN_IDS;
 46  
 
 47  
     /** Prefix for exception when getting token by given id. */
 48  
     private static final String TOKEN_ID_EXCEPTION_PREFIX = "given id ";
 49  
 
 50  
     /** Prefix for exception when getting token by given name. */
 51  
     private static final String TOKEN_NAME_EXCEPTION_PREFIX = "given name ";
 52  
 
 53  
     // initialise the constants
 54  
     static {
 55  
         final ImmutableMap.Builder<String, Integer> builder =
 56  6
                 ImmutableMap.builder();
 57  6
         final Field[] fields = TokenTypes.class.getDeclaredFields();
 58  6
         String[] tempTokenValueToName = CommonUtils.EMPTY_STRING_ARRAY;
 59  1026
         for (final Field field : fields) {
 60  
             // Only process the int declarations.
 61  1020
             if (field.getType() != Integer.TYPE) {
 62  6
                 continue;
 63  
             }
 64  
 
 65  1014
             final String name = field.getName();
 66  1014
             final int tokenValue = getIntFromField(field, name);
 67  1014
             builder.put(name, tokenValue);
 68  1014
             if (tokenValue > tempTokenValueToName.length - 1) {
 69  168
                 final String[] temp = new String[tokenValue + 1];
 70  168
                 System.arraycopy(tempTokenValueToName, 0,
 71  
                         temp, 0, tempTokenValueToName.length);
 72  168
                 tempTokenValueToName = temp;
 73  
             }
 74  1014
             tempTokenValueToName[tokenValue] = name;
 75  
         }
 76  
 
 77  6
         TOKEN_NAME_TO_VALUE = builder.build();
 78  6
         TOKEN_VALUE_TO_NAME = tempTokenValueToName;
 79  6
         TOKEN_IDS = TOKEN_NAME_TO_VALUE.values().stream().mapToInt(Integer::intValue).toArray();
 80  6
     }
 81  
 
 82  
     /** Stop instances being created. **/
 83  1
     private TokenUtils() {
 84  1
     }
 85  
 
 86  
     /**
 87  
      * Gets the value of a static or instance field of type int or of another primitive type
 88  
      * convertible to type int via a widening conversion. Does not throw any checked exceptions.
 89  
      * @param field from which the int should be extracted
 90  
      * @param object to extract the int value from
 91  
      * @return the value of the field converted to type int
 92  
      * @throws IllegalStateException if this Field object is enforcing Java language access control
 93  
      *         and the underlying field is inaccessible
 94  
      * @see Field#getInt(Object)
 95  
      */
 96  
     public static int getIntFromField(Field field, Object object) {
 97  
         try {
 98  1340
             return field.getInt(object);
 99  
         }
 100  1
         catch (final IllegalAccessException exception) {
 101  1
             throw new IllegalStateException(exception);
 102  
         }
 103  
     }
 104  
 
 105  
     /**
 106  
      * Get total number of TokenTypes.
 107  
      * @return total number of TokenTypes.
 108  
      */
 109  
     public static int getTokenTypesTotalNumber() {
 110  2
         return TOKEN_IDS.length;
 111  
     }
 112  
 
 113  
     /**
 114  
      * Get all token IDs that are available in TokenTypes.
 115  
      * @return array of token IDs
 116  
      */
 117  
     public static int[] getAllTokenIds() {
 118  77
         final int[] safeCopy = new int[TOKEN_IDS.length];
 119  77
         System.arraycopy(TOKEN_IDS, 0, safeCopy, 0, TOKEN_IDS.length);
 120  77
         return safeCopy;
 121  
     }
 122  
 
 123  
     /**
 124  
      * Returns the name of a token for a given ID.
 125  
      * @param id the ID of the token name to get
 126  
      * @return a token name
 127  
      */
 128  
     public static String getTokenName(int id) {
 129  1264193
         if (id > TOKEN_VALUE_TO_NAME.length - 1) {
 130  1
             throw new IllegalArgumentException(TOKEN_ID_EXCEPTION_PREFIX + id);
 131  
         }
 132  1264192
         final String name = TOKEN_VALUE_TO_NAME[id];
 133  1264192
         if (name == null) {
 134  1
             throw new IllegalArgumentException(TOKEN_ID_EXCEPTION_PREFIX + id);
 135  
         }
 136  1264191
         return name;
 137  
     }
 138  
 
 139  
     /**
 140  
      * Returns the ID of a token for a given name.
 141  
      * @param name the name of the token ID to get
 142  
      * @return a token ID
 143  
      */
 144  
     public static int getTokenId(String name) {
 145  10540
         final Integer id = TOKEN_NAME_TO_VALUE.get(name);
 146  10540
         if (id == null) {
 147  1
             throw new IllegalArgumentException(TOKEN_NAME_EXCEPTION_PREFIX + name);
 148  
         }
 149  10539
         return id;
 150  
     }
 151  
 
 152  
     /**
 153  
      * Returns the short description of a token for a given name.
 154  
      * @param name the name of the token ID to get
 155  
      * @return a short description
 156  
      */
 157  
     public static String getShortDescription(String name) {
 158  8
         if (!TOKEN_NAME_TO_VALUE.containsKey(name)) {
 159  1
             throw new IllegalArgumentException(TOKEN_NAME_EXCEPTION_PREFIX + name);
 160  
         }
 161  
 
 162  7
         final String tokenTypes =
 163  
             "com.puppycrawl.tools.checkstyle.api.tokentypes";
 164  7
         final ResourceBundle bundle = ResourceBundle.getBundle(tokenTypes, Locale.ROOT);
 165  7
         return bundle.getString(name);
 166  
     }
 167  
 
 168  
     /**
 169  
      * Is argument comment-related type (SINGLE_LINE_COMMENT,
 170  
      * BLOCK_COMMENT_BEGIN, BLOCK_COMMENT_END, COMMENT_CONTENT).
 171  
      * @param type
 172  
      *        token type.
 173  
      * @return true if type is comment-related type.
 174  
      */
 175  
     public static boolean isCommentType(int type) {
 176  2003577
         return type == TokenTypes.SINGLE_LINE_COMMENT
 177  
                 || type == TokenTypes.BLOCK_COMMENT_BEGIN
 178  
                 || type == TokenTypes.BLOCK_COMMENT_END
 179  
                 || type == TokenTypes.COMMENT_CONTENT;
 180  
     }
 181  
 
 182  
     /**
 183  
      * Is argument comment-related type name (SINGLE_LINE_COMMENT,
 184  
      * BLOCK_COMMENT_BEGIN, BLOCK_COMMENT_END, COMMENT_CONTENT).
 185  
      * @param type
 186  
      *        token type name.
 187  
      * @return true if type is comment-related type name.
 188  
      */
 189  
     public static boolean isCommentType(String type) {
 190  9886
         return isCommentType(getTokenId(type));
 191  
     }
 192  
 
 193  
     /**
 194  
      * Finds the first {@link Optional} child token of {@link DetailAST} root node
 195  
      * which matches the given predicate.
 196  
      * @param root root node.
 197  
      * @param predicate predicate.
 198  
      * @return {@link Optional} of {@link DetailAST} node which matches the predicate.
 199  
      */
 200  
     public static Optional<DetailAST> findFirstTokenByPredicate(DetailAST root,
 201  
                                                                 Predicate<DetailAST> predicate) {
 202  86
         Optional<DetailAST> result = Optional.empty();
 203  139
         for (DetailAST ast = root.getFirstChild(); ast != null; ast = ast.getNextSibling()) {
 204  119
             if (predicate.test(ast)) {
 205  66
                 result = Optional.of(ast);
 206  66
                 break;
 207  
             }
 208  
         }
 209  86
         return result;
 210  
     }
 211  
 }