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 */
16package dagger.internal.codegen.writer;
17
18import com.google.common.collect.Lists;
19import com.google.common.collect.Maps;
20import java.util.List;
21import java.util.Map;
22import javax.lang.model.element.TypeElement;
23import javax.lang.model.type.TypeMirror;
24
25/**
26 * Only named types. Doesn't cover anonymous inner classes.
27 */
28public 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
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
45  public ClassName name() {
46    return name;
47  }
48
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
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
62  public MethodWriter addMethod(TypeName returnType, String name) {
63    MethodWriter methodWriter = new MethodWriter(returnType, name);
64    methodWriters.add(methodWriter);
65    return methodWriter;
66  }
67
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
75  public ClassWriter addNestedClass(String name) {
76    ClassWriter innerClassWriter = new ClassWriter(this.name.nestedClassNamed(name));
77    nestedTypeWriters.add(innerClassWriter);
78    return innerClassWriter;
79  }
80
81  public void addImplementedType(TypeName typeReference) {
82    implementedTypes.add(typeReference);
83  }
84
85  public void addImplementedType(TypeElement typeElement) {
86    implementedTypes.add(ClassName.fromTypeElement(typeElement));
87  }
88
89  public FieldWriter addField(Class<?> type, String name) {
90    return addField(ClassName.fromClass(type), name);
91  }
92
93  public FieldWriter addField(TypeElement type, String name) {
94    return addField(ClassName.fromTypeElement(type), name);
95  }
96
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