1 /* 2 * Copyright (C) 2014 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.internal.codegen.base; 18 19 import static com.google.common.base.Preconditions.checkElementIndex; 20 21 import com.google.common.base.Function; 22 import com.google.common.collect.Iterables; 23 24 /** 25 * A formatter which transforms an instance of a particular type into a string 26 * representation. 27 * 28 * @param <T> the type of the object to be transformed. 29 */ 30 public abstract class Formatter<T> implements Function<T, String> { 31 32 public static final String INDENT = " "; 33 public static final String DOUBLE_INDENT = INDENT + INDENT; 34 private static final int LIST_LIMIT = 10; 35 36 /** 37 * Performs the transformation of an object into a string representation. 38 */ format(T object)39 public abstract String format(T object); 40 41 /** 42 * Performs the transformation of an object into a string representation in conformity with the 43 * {@link Function}{@code <T, String>} contract, delegating to {@link #format(Object)}. 44 * 45 * @deprecated Call {@link #format(Object)} instead. This method exists to make formatters easy to 46 * use when functions are required, but shouldn't be called directly. 47 */ 48 @SuppressWarnings("javadoc") 49 @Deprecated 50 @Override apply(T object)51 public final String apply(T object) { 52 return format(object); 53 } 54 55 /** Formats {@code items}, one per line. Stops after {@value #LIST_LIMIT} items. */ formatIndentedList( StringBuilder builder, Iterable<? extends T> items, int indentLevel)56 public void formatIndentedList( 57 StringBuilder builder, Iterable<? extends T> items, int indentLevel) { 58 for (T item : Iterables.limit(items, LIST_LIMIT)) { 59 String formatted = format(item); 60 if (formatted.isEmpty()) { 61 continue; 62 } 63 builder.append('\n'); 64 appendIndent(builder, indentLevel); 65 builder.append(formatted); 66 } 67 int numberOfOtherItems = Iterables.size(items) - LIST_LIMIT; 68 if (numberOfOtherItems > 0) { 69 builder.append('\n'); 70 appendIndent(builder, indentLevel); 71 builder.append("and ").append(numberOfOtherItems).append(" other"); 72 } 73 if (numberOfOtherItems > 1) { 74 builder.append('s'); 75 } 76 } 77 appendIndent(StringBuilder builder, int indentLevel)78 private void appendIndent(StringBuilder builder, int indentLevel) { 79 for (int i = 0; i < indentLevel; i++) { 80 builder.append(INDENT); 81 } 82 } 83 formatArgumentInList(int index, int size, CharSequence name)84 public static String formatArgumentInList(int index, int size, CharSequence name) { 85 checkElementIndex(index, size); 86 StringBuilder builder = new StringBuilder(); 87 if (index > 0) { 88 builder.append("…, "); 89 } 90 builder.append(name); 91 if (index < size - 1) { 92 builder.append(", …"); 93 } 94 return builder.toString(); 95 } 96 } 97