• 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 static dagger.internal.codegen.xprocessing.XTypes.isPrimitive;
20 
21 import androidx.room.compiler.processing.XRawType;
22 import androidx.room.compiler.processing.XType;
23 import com.squareup.javapoet.CodeBlock;
24 
25 /**
26  * Encapsulates a {@link CodeBlock} for an <a
27  * href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html">expression</a> and the
28  * {@link XType} that it represents from the perspective of the compiler. Consider the following
29  * example:
30  *
31  * <pre><code>
32  *   {@literal @SuppressWarnings("rawtypes")}
33  *   private Provider fooImplProvider = DoubleCheck.provider(FooImpl_Factory.create());
34  * </code></pre>
35  *
36  * <p>An {@code Expression} for {@code fooImplProvider.get()} would have a {@link #type()} of {@code
37  * java.lang.Object} and not {@code FooImpl}.
38  */
39 public final class Expression {
40   private final ExpressionType type;
41   private final CodeBlock codeBlock;
42 
Expression(ExpressionType type, CodeBlock codeBlock)43   private Expression(ExpressionType type, CodeBlock codeBlock) {
44     this.type = type;
45     this.codeBlock = codeBlock;
46   }
47 
48   /** Creates a new {@link Expression} with a {@link XType} and {@link CodeBlock}. */
create(XType type, CodeBlock expression)49   public static Expression create(XType type, CodeBlock expression) {
50     return new Expression(ExpressionType.create(type), expression);
51   }
52 
53   /** Creates a new {@link Expression} with a {@link ExpressionType} and {@link CodeBlock}. */
create(ExpressionType type, CodeBlock expression)54   public static Expression create(ExpressionType type, CodeBlock expression) {
55     return new Expression(type, expression);
56   }
57 
58   /**
59    * Creates a new {@link Expression} with a {@link XType}, {@linkplain CodeBlock#of(String,
60    * Object[]) format, and arguments}.
61    */
create(XType type, String format, Object... args)62   public static Expression create(XType type, String format, Object... args) {
63     return create(type, CodeBlock.of(format, args));
64   }
65 
66   /** Returns a new expression that casts the current expression to {@code newType}. */
castTo(XType newType)67   public Expression castTo(XType newType) {
68     return create(newType, CodeBlock.of("($T) $L", newType.getTypeName(), codeBlock));
69   }
70 
71   /** Returns a new expression that casts the current expression to {@code newType}. */
castTo(XRawType newRawType)72   public Expression castTo(XRawType newRawType) {
73     return create(
74         ExpressionType.create(newRawType, type.getProcessingEnv()),
75         CodeBlock.of("($T) $L", newRawType.getTypeName(), codeBlock));
76   }
77 
78   /**
79    * Returns a new expression that {@link #castTo(XType)} casts the current expression to its boxed
80    * type if this expression has a primitive type.
81    */
box()82   public Expression box() {
83     return type.asType().isPresent() && isPrimitive(type.asType().get())
84         ? castTo(type.asType().get().boxed())
85         : this;
86   }
87 
88   /** The {@link XType type} to which the expression evaluates. */
type()89   public ExpressionType type() {
90     return type;
91   }
92 
93   /** The code of the expression. */
codeBlock()94   public CodeBlock codeBlock() {
95     return codeBlock;
96   }
97 
98   @Override
toString()99   public String toString() {
100     return String.format("[%s] %s", type.getTypeName(), codeBlock);
101   }
102 }
103