• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.google.common.base.Preconditions.checkState;
20 
21 import androidx.room.compiler.processing.XProcessingEnv;
22 import androidx.room.compiler.processing.XRawType;
23 import androidx.room.compiler.processing.XType;
24 import androidx.room.compiler.processing.compat.XConverters;
25 import com.squareup.javapoet.ClassName;
26 import com.squareup.javapoet.TypeName;
27 import dagger.internal.codegen.xprocessing.XProcessingEnvs;
28 import dagger.internal.codegen.xprocessing.XTypes;
29 import java.util.Optional;
30 
31 /**
32  * The type of an {@link Expression} that can represent both {@link XType} or {@link XRawType}.
33  */
34 // TODO(bcorso): It would be nice if XType and XRawType shared some basic interface with some of
35 // the common methods so that we wouldn't need to create this ExpressionType to make things work.
36 public final class ExpressionType {
create(XType type)37   public static ExpressionType create(XType type) {
38     return new ExpressionType(
39         Optional.of(type), Optional.empty(), XConverters.getProcessingEnv(type));
40   }
41 
create(XRawType type, XProcessingEnv processingEnv)42   static ExpressionType create(XRawType type, XProcessingEnv processingEnv) {
43     return new ExpressionType(Optional.empty(), Optional.of(type), processingEnv);
44   }
45 
createRawType(XType type)46   public static ExpressionType createRawType(XType type) {
47     return create(type.getRawType(), XConverters.getProcessingEnv(type));
48   }
49 
50   private final Optional<XType> optionalType;
51   private final Optional<XRawType> optionalRawType;
52   private final XProcessingEnv processingEnv;
53 
ExpressionType( Optional<XType> optionalType, Optional<XRawType> optionalRawType, XProcessingEnv processingEnv)54   private ExpressionType(
55       Optional<XType> optionalType,
56       Optional<XRawType> optionalRawType,
57       XProcessingEnv processingEnv) {
58     this.optionalType = optionalType;
59     this.optionalRawType = optionalRawType;
60     this.processingEnv = processingEnv;
61     checkState(optionalType.isPresent() || optionalRawType.isPresent());
62   }
63 
unwrapType()64   public ExpressionType unwrapType() {
65     return optionalType.isPresent() && !XTypes.isRawParameterizedType(optionalType.get())
66         ? ExpressionType.create(XProcessingEnvs.unwrapType(optionalType.get()))
67         : ExpressionType.create(processingEnv.requireType(TypeName.OBJECT));
68   }
69 
wrapType(ClassName wrapper)70   public ExpressionType wrapType(ClassName wrapper) {
71     return optionalType.isPresent()
72         ? ExpressionType.create(
73             XProcessingEnvs.wrapType(wrapper, optionalType.get(), processingEnv))
74         // If the current type is a raw type then we just return the wrapper type as a raw type too.
75         // This isn't really accurate, but it's the best we can do with XProcessing's type system.
76         // For example, if the current type is a raw type, Foo, then Provider<Foo> is not allowed so
77         // we return the raw Provider type.
78         : ExpressionType.createRawType(processingEnv.requireType(wrapper));
79   }
80 
rewrapType(ClassName wrapper)81   public ExpressionType rewrapType(ClassName wrapper) {
82     return optionalType.isPresent()
83         ? ExpressionType.create(XTypes.rewrapType(optionalType.get(), wrapper))
84         : ExpressionType.createRawType(processingEnv.requireType(wrapper));
85   }
86 
getTypeName()87   public TypeName getTypeName() {
88     return optionalType.isPresent()
89         ? optionalType.get().getTypeName()
90         : optionalRawType.get().getTypeName();
91   }
92 
isSameType(XType type)93   public boolean isSameType(XType type) {
94     return optionalType.isPresent()
95         ? optionalType.get().isSameType(type)
96         : XTypes.isRawParameterizedType(type)
97             && getTypeName().equals(type.getTypeName());
98   }
99 
isSameType(XRawType type)100   public boolean isSameType(XRawType type) {
101     return getTypeName().equals(type.getTypeName());
102   }
103 
isAssignableTo(XType type)104   public boolean isAssignableTo(XType type) {
105     return optionalType.isPresent()
106         ? type.isAssignableFrom(optionalType.get())
107         : type.getRawType().isAssignableFrom(optionalRawType.get());
108   }
109 
isAssignableTo(XRawType rawType)110   public boolean isAssignableTo(XRawType rawType) {
111     return optionalType.isPresent()
112         ? rawType.isAssignableFrom(optionalType.get())
113         : rawType.isAssignableFrom(optionalRawType.get());
114   }
115 
asType()116   Optional<XType> asType() {
117     return optionalType;
118   }
119 
asRawType()120   Optional<XRawType> asRawType() {
121     return optionalRawType;
122   }
123 
getProcessingEnv()124   XProcessingEnv getProcessingEnv() {
125     return processingEnv;
126   }
127 }
128