• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.javapoet;
18 
19 import static com.squareup.javapoet.MethodSpec.methodBuilder;
20 import static com.squareup.javapoet.TypeSpec.anonymousClassBuilder;
21 import static dagger.internal.codegen.javapoet.TypeNames.daggerProviderOf;
22 import static dagger.internal.codegen.javapoet.TypeNames.lazyOf;
23 import static java.util.stream.StreamSupport.stream;
24 import static javax.lang.model.element.Modifier.PUBLIC;
25 
26 import androidx.room.compiler.processing.XType;
27 import com.squareup.javapoet.ClassName;
28 import com.squareup.javapoet.CodeBlock;
29 import com.squareup.javapoet.ParameterSpec;
30 import com.squareup.javapoet.TypeName;
31 import java.util.stream.Collector;
32 
33 /** Convenience methods for creating {@link CodeBlock}s. */
34 public final class CodeBlocks {
35   /**
36    * Joins {@link CodeBlock} instances in a manner suitable for use as method parameters (or
37    * arguments).
38    */
toParametersCodeBlock()39   public static Collector<CodeBlock, ?, CodeBlock> toParametersCodeBlock() {
40     // TODO(ronshapiro,jakew): consider adding zero-width spaces to help line breaking when the
41     // formatter is off. If not, inline this
42     return CodeBlock.joining(", ");
43   }
44 
45   /** Concatenates {@link CodeBlock} instances separated by newlines for readability. */
toConcatenatedCodeBlock()46   public static Collector<CodeBlock, ?, CodeBlock> toConcatenatedCodeBlock() {
47     return CodeBlock.joining("\n", "", "\n");
48   }
49 
50   /** Returns a comma-separated version of {@code codeBlocks} as one unified {@link CodeBlock}. */
makeParametersCodeBlock(Iterable<CodeBlock> codeBlocks)51   public static CodeBlock makeParametersCodeBlock(Iterable<CodeBlock> codeBlocks) {
52     return stream(codeBlocks.spliterator(), false).collect(toParametersCodeBlock());
53   }
54 
55   /**
56    * Returns a comma-separated {@link CodeBlock} using the name of every parameter in {@code
57    * parameters}.
58    */
parameterNames(Iterable<ParameterSpec> parameters)59   public static CodeBlock parameterNames(Iterable<ParameterSpec> parameters) {
60     // TODO(ronshapiro): Add DaggerStreams.stream(Iterable)
61     return stream(parameters.spliterator(), false)
62         .map(p -> CodeBlock.of("$N", p))
63         .collect(toParametersCodeBlock());
64   }
65 
66   /**
67    * Returns one unified {@link CodeBlock} which joins each item in {@code codeBlocks} with a
68    * newline.
69    */
concat(Iterable<CodeBlock> codeBlocks)70   public static CodeBlock concat(Iterable<CodeBlock> codeBlocks) {
71     return stream(codeBlocks.spliterator(), false).collect(toConcatenatedCodeBlock());
72   }
73 
74   /**
75    * Returns an anonymous {@link javax.inject.Provider} class with the single {@link
76    * javax.inject.Provider#get()} method that returns the given {@code expression}.
77    */
anonymousProvider(Expression expression)78   public static CodeBlock anonymousProvider(Expression expression) {
79     return anonymousProvider(
80         expression.type().getTypeName(), CodeBlock.of("return $L;", expression.codeBlock()));
81   }
82 
83   /**
84    * Returns an anonymous {@link javax.inject.Provider} class with the single {@link
85    * javax.inject.Provider#get()} method implemented by {@code body}.
86    */
anonymousProvider(TypeName providedType, CodeBlock body)87   public static CodeBlock anonymousProvider(TypeName providedType, CodeBlock body) {
88     return CodeBlock.of(
89         "$L",
90         anonymousClassBuilder("")
91             .superclass(daggerProviderOf(providedType))
92             .addMethod(
93                 methodBuilder("get")
94                     .addAnnotation(Override.class)
95                     .addModifiers(PUBLIC)
96                     .returns(providedType)
97                     .addCode(body)
98                     .build())
99             .build());
100   }
101 
anonymousLazy(TypeName providedType, CodeBlock body)102   public static CodeBlock anonymousLazy(TypeName providedType, CodeBlock body) {
103     return CodeBlock.of(
104         "$L",
105         anonymousClassBuilder("")
106             .superclass(lazyOf(providedType))
107             .addMethod(
108                 methodBuilder("get")
109                     .addAnnotation(Override.class)
110                     .addModifiers(PUBLIC)
111                     .returns(providedType)
112                     .addCode(body)
113                     .build())
114             .build());
115   }
116 
117   /** Returns {@code expression} cast to a type. */
cast(CodeBlock expression, ClassName castTo)118   public static CodeBlock cast(CodeBlock expression, ClassName castTo) {
119     return CodeBlock.of("($T) $L", castTo, expression);
120   }
121 
122   /** Returns {@code expression} cast to a type. */
cast(CodeBlock expression, Class<?> castTo)123   public static CodeBlock cast(CodeBlock expression, Class<?> castTo) {
124     return CodeBlock.of("($T) $L", castTo, expression);
125   }
126 
type(XType type)127   public static CodeBlock type(XType type) {
128     return CodeBlock.of("$T", type.getTypeName());
129   }
130 
stringLiteral(String toWrap)131   public static CodeBlock stringLiteral(String toWrap) {
132     return CodeBlock.of("$S", toWrap);
133   }
134 
CodeBlocks()135   private CodeBlocks() {}
136 }
137