• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 com.google.auto.common.MoreTypes;
20 import com.squareup.javapoet.CodeBlock;
21 import dagger.internal.codegen.langmodel.DaggerTypes;
22 import javax.lang.model.type.TypeMirror;
23 
24 /**
25  * Encapsulates a {@link CodeBlock} for an <a
26  * href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html">expression</a> and the
27  * {@link TypeMirror} that it represents from the perspective of the compiler. Consider the
28  * following example:
29  *
30  * <pre><code>
31  *   {@literal @SuppressWarnings("rawtypes")}
32  *   private Provider fooImplProvider = DoubleCheck.provider(FooImpl_Factory.create());
33  * </code></pre>
34  *
35  * <p>An {@code Expression} for {@code fooImplProvider.get()} would have a {@link #type()} of {@code
36  * java.lang.Object} and not {@code FooImpl}.
37  */
38 public final class Expression {
39   private final TypeMirror type;
40   private final CodeBlock codeBlock;
41 
Expression(TypeMirror type, CodeBlock codeBlock)42   private Expression(TypeMirror type, CodeBlock codeBlock) {
43     this.type = type;
44     this.codeBlock = codeBlock;
45   }
46 
47   /** Creates a new {@link Expression} with a {@link TypeMirror} and {@link CodeBlock}. */
create(TypeMirror type, CodeBlock expression)48   public static Expression create(TypeMirror type, CodeBlock expression) {
49     return new Expression(type, expression);
50   }
51 
52   /**
53    * Creates a new {@link Expression} with a {@link TypeMirror}, {@linkplain CodeBlock#of(String,
54    * Object[]) format, and arguments}.
55    */
create(TypeMirror type, String format, Object... args)56   public static Expression create(TypeMirror type, String format, Object... args) {
57     return create(type, CodeBlock.of(format, args));
58   }
59 
60   /** Returns a new expression that casts the current expression to {@code newType}. */
61   // TODO(ronshapiro): consider overloads that take a Types and Elements and only cast if necessary,
62   // or just embedding a Types/Elements instance in an Expression.
castTo(TypeMirror newType)63   public Expression castTo(TypeMirror newType) {
64     return create(newType, "($T) $L", newType, codeBlock);
65   }
66 
67   /**
68    * Returns a new expression that {@link #castTo(TypeMirror)} casts the current expression to its
69    * boxed type if this expression has a primitive type.
70    */
box(DaggerTypes types)71   public Expression box(DaggerTypes types) {
72     return type.getKind().isPrimitive()
73         ? castTo(types.boxedClass(MoreTypes.asPrimitiveType(type)).asType())
74         : this;
75   }
76 
77   /** The {@link TypeMirror type} to which the expression evaluates. */
type()78   public TypeMirror type() {
79     return type;
80   }
81 
82   /** The code of the expression. */
codeBlock()83   public CodeBlock codeBlock() {
84     return codeBlock;
85   }
86 
87   @Override
toString()88   public String toString() {
89     return String.format("[%s] %s", type, codeBlock);
90   }
91 }
92