1 /*
2  * Copyright (C) 2014 Google, Inc.
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 package dagger.internal.codegen.writer;
17 
18 import com.google.common.collect.Lists;
19 import com.google.common.collect.Maps;
20 import java.util.List;
21 import java.util.Map;
22 import javax.lang.model.element.TypeElement;
23 import javax.lang.model.type.TypeMirror;
24 
25 /**
26  * Only named types. Doesn't cover anonymous inner classes.
27  */
28 public abstract class TypeWriter /* ha ha */ extends Modifiable
29     implements Writable, HasTypeName, HasClassReferences {
30   final ClassName name;
31   final List<TypeName> implementedTypes;
32   final List<MethodWriter> methodWriters;
33   final List<TypeWriter> nestedTypeWriters;
34   final Map<String, FieldWriter> fieldWriters;
35 
TypeWriter(ClassName name)36   TypeWriter(ClassName name) {
37     this.name = name;
38     this.implementedTypes = Lists.newArrayList();
39     this.methodWriters = Lists.newArrayList();
40     this.nestedTypeWriters = Lists.newArrayList();
41     this.fieldWriters = Maps.newLinkedHashMap();
42   }
43 
44   @Override
name()45   public ClassName name() {
46     return name;
47   }
48 
addMethod(TypeWriter returnType, String name)49   public MethodWriter addMethod(TypeWriter returnType, String name) {
50     MethodWriter methodWriter = new MethodWriter(returnType.name, name);
51     methodWriters.add(methodWriter);
52     return methodWriter;
53   }
54 
addMethod(TypeMirror returnType, String name)55   public MethodWriter addMethod(TypeMirror returnType, String name) {
56     MethodWriter methodWriter =
57         new MethodWriter(TypeNames.forTypeMirror(returnType), name);
58     methodWriters.add(methodWriter);
59     return methodWriter;
60   }
61 
addMethod(TypeName returnType, String name)62   public MethodWriter addMethod(TypeName returnType, String name) {
63     MethodWriter methodWriter = new MethodWriter(returnType, name);
64     methodWriters.add(methodWriter);
65     return methodWriter;
66   }
67 
addMethod(Class<?> returnType, String name)68   public MethodWriter addMethod(Class<?> returnType, String name) {
69     MethodWriter methodWriter =
70         new MethodWriter(ClassName.fromClass(returnType), name);
71     methodWriters.add(methodWriter);
72     return methodWriter;
73   }
74 
addNestedClass(String name)75   public ClassWriter addNestedClass(String name) {
76     ClassWriter innerClassWriter = new ClassWriter(this.name.nestedClassNamed(name));
77     nestedTypeWriters.add(innerClassWriter);
78     return innerClassWriter;
79   }
80 
addImplementedType(TypeName typeReference)81   public void addImplementedType(TypeName typeReference) {
82     implementedTypes.add(typeReference);
83   }
84 
addImplementedType(TypeElement typeElement)85   public void addImplementedType(TypeElement typeElement) {
86     implementedTypes.add(ClassName.fromTypeElement(typeElement));
87   }
88 
addField(Class<?> type, String name)89   public FieldWriter addField(Class<?> type, String name) {
90     return addField(ClassName.fromClass(type), name);
91   }
92 
addField(TypeElement type, String name)93   public FieldWriter addField(TypeElement type, String name) {
94     return addField(ClassName.fromTypeElement(type), name);
95   }
96 
addField(TypeName type, String name)97   public FieldWriter addField(TypeName type, String name) {
98     String candidateName = name;
99     int differentiator = 1;
100     while (fieldWriters.containsKey(candidateName)) {
101       candidateName = name + differentiator;
102       differentiator++;
103     }
104     FieldWriter fieldWriter = new FieldWriter(type, candidateName);
105     fieldWriters.put(candidateName, fieldWriter);
106     return fieldWriter;
107   }
108 }
109