1 /* 2 * Copyright (C) 2019 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.hilt.processor.internal; 18 19 20 import androidx.room.compiler.processing.XElement; 21 import com.google.common.base.Preconditions; 22 import com.google.errorprone.annotations.FormatMethod; 23 import com.google.errorprone.annotations.FormatString; 24 import java.util.Collection; 25 import javax.annotation.Nullable; 26 27 /** Static helper methods for throwing errors during code generation. */ 28 public final class ProcessorErrors { 29 /** 30 * Ensures the truth of an expression involving the state of the calling instance, but not 31 * involving any parameters to the calling method. 32 * 33 * @param expression a boolean expression 34 * @param errorMessage the exception message to use if the check fails; will be converted to a 35 * string using {@link String#valueOf(Object)} 36 * @throws BadInputException if {@code expression} is false 37 */ checkState(boolean expression, @Nullable Object errorMessage)38 public static void checkState(boolean expression, @Nullable Object errorMessage) { 39 if (!expression) { 40 throw new BadInputException(String.valueOf(errorMessage)); 41 } 42 } 43 44 /** 45 * Ensures the truth of an expression involving the state of the calling instance, but not 46 * involving any parameters to the calling method. 47 * 48 * @param expression a boolean expression 49 * @param errorMessageTemplate a template for the exception message should the check fail. The 50 * message is formed by replacing each {@code %s} placeholder in the template with an 51 * argument. These are matched by position - the first {@code %s} gets {@code 52 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in 53 * square braces. Unmatched placeholders will be left as-is. 54 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 55 * are converted to strings using {@link String#valueOf(Object)}. 56 * @throws BadInputException if {@code expression} is false 57 * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or 58 * {@code errorMessageArgs} is null (don't let this happen) 59 */ 60 @FormatMethod checkState( boolean expression, @Nullable @FormatString String errorMessageTemplate, @Nullable Object... errorMessageArgs)61 public static void checkState( 62 boolean expression, 63 @Nullable @FormatString String errorMessageTemplate, 64 @Nullable Object... errorMessageArgs) { 65 if (!expression) { 66 throw new BadInputException(String.format(errorMessageTemplate, errorMessageArgs)); 67 } 68 } 69 70 /** 71 * Ensures the truth of an expression involving the state of the calling instance, but not 72 * involving any parameters to the calling method. 73 * 74 * @param expression a boolean expression 75 * @param badElement the element that was at fault 76 * @param errorMessage the exception message to use if the check fails; will be converted to a 77 * string using {@link String#valueOf(Object)} 78 * @throws BadInputException if {@code expression} is false 79 */ checkState( boolean expression, XElement badElement, @Nullable Object errorMessage)80 public static void checkState( 81 boolean expression, XElement badElement, @Nullable Object errorMessage) { 82 Preconditions.checkNotNull(badElement); 83 if (!expression) { 84 throw new BadInputException(String.valueOf(errorMessage), badElement); 85 } 86 } 87 88 /** 89 * Ensures the truth of an expression involving the state of the calling instance, but not 90 * involving any parameters to the calling method. 91 * 92 * <p>e.g. checkState(foo.isABar(), "Failed because of %s is not a bar", foo); 93 * 94 * @param expression a boolean expression 95 * @param badElement the element that was at fault 96 * @param errorMessageTemplate a template for the exception message should the check fail. The 97 * message is formed by replacing each {@code %s} placeholder in the template with an 98 * argument. These are matched by position - the first {@code %s} gets {@code 99 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in 100 * square braces. Unmatched placeholders will be left as-is. 101 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 102 * are converted to strings using {@link String#valueOf(Object)}. 103 * @throws BadInputException if {@code expression} is false 104 * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or 105 * {@code errorMessageArgs} is null (don't let this happen) 106 */ 107 @FormatMethod checkState( boolean expression, XElement badElement, @Nullable @FormatString String errorMessageTemplate, @Nullable Object... errorMessageArgs)108 public static void checkState( 109 boolean expression, 110 XElement badElement, 111 @Nullable @FormatString String errorMessageTemplate, 112 @Nullable Object... errorMessageArgs) { 113 Preconditions.checkNotNull(badElement); 114 if (!expression) { 115 throw new BadInputException( 116 String.format(errorMessageTemplate, errorMessageArgs), badElement); 117 } 118 } 119 120 /** 121 * Ensures the truth of an expression involving the state of the calling instance, but not 122 * involving any parameters to the calling method. 123 * 124 * @param expression a boolean expression 125 * @param badElements the elements that were at fault 126 * @param errorMessageTemplate a template for the exception message should the check fail. The 127 * message is formed by replacing each {@code %s} placeholder in the template with an 128 * argument. These are matched by position - the first {@code %s} gets {@code 129 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in 130 * square braces. Unmatched placeholders will be left as-is. 131 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 132 * are converted to strings using {@link String#valueOf(Object)}. 133 * @throws BadInputException if {@code expression} is false 134 * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or 135 * {@code errorMessageArgs} is null (don't let this happen) 136 */ 137 // TODO(bcorso): Rename this checkState once the javac API is removed (overloading doesn't work 138 // here since they have the same erasured signature). 139 @FormatMethod checkStateX( boolean expression, Collection<? extends XElement> badElements, @Nullable @FormatString String errorMessageTemplate, @Nullable Object... errorMessageArgs)140 public static void checkStateX( 141 boolean expression, 142 Collection<? extends XElement> badElements, 143 @Nullable @FormatString String errorMessageTemplate, 144 @Nullable Object... errorMessageArgs) { 145 Preconditions.checkNotNull(badElements); 146 if (!expression) { 147 Preconditions.checkState(!badElements.isEmpty()); 148 throw new BadInputException( 149 String.format(errorMessageTemplate, errorMessageArgs), badElements); 150 } 151 } 152 ProcessorErrors()153 private ProcessorErrors() {} 154 } 155