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.FluentIterable;
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableMap;
21import com.google.common.collect.Maps;
22import java.io.IOException;
23import java.util.Map;
24import java.util.Set;
25import javax.lang.model.element.TypeElement;
26
27import static com.google.common.base.Preconditions.checkArgument;
28
29public final class ConstructorWriter extends Modifiable implements Writable, HasClassReferences {
30  private final String name;
31  private final Map<String, VariableWriter> parameterWriters;
32  private final BlockWriter blockWriter;
33
34  ConstructorWriter(String name) {
35    this.name = name;
36    this.parameterWriters = Maps.newLinkedHashMap();
37    this.blockWriter = new BlockWriter();
38  }
39
40  public VariableWriter addParameter(Class<?> type, String name) {
41    return addParameter(ClassName.fromClass(type), name);
42  }
43
44  public VariableWriter addParameter(TypeElement type, String name) {
45    return addParameter(ClassName.fromTypeElement(type), name);
46  }
47
48  public VariableWriter addParameter(TypeWriter type, String name) {
49    return addParameter(type.name, name);
50  }
51
52  public VariableWriter addParameter(TypeName type, String name) {
53    VariableWriter parameterWriter = new VariableWriter(type, name);
54    parameterWriters.put(name, parameterWriter);
55    return parameterWriter;
56  }
57
58  public Map<String, TypeName> parameters() {
59    ImmutableMap.Builder<String, TypeName> params = ImmutableMap.builder();
60    for (Map.Entry<String, VariableWriter> entry : parameterWriters.entrySet()) {
61      params.put(entry.getKey(), entry.getValue().type());
62    }
63    return params.build();
64  }
65
66  public BlockWriter body() {
67    return blockWriter;
68  }
69
70  private VariableWriter addParameter(ClassName type, String name) {
71    checkArgument(!parameterWriters.containsKey(name));
72    VariableWriter parameterWriter = new VariableWriter(type, name);
73    parameterWriters.put(name, parameterWriter);
74    return parameterWriter;
75  }
76
77  @Override
78  public Set<ClassName> referencedClasses() {
79    return FluentIterable.from(ImmutableList.<HasClassReferences>of())
80        .append(parameterWriters.values())
81        .append(annotations)
82        .append(blockWriter)
83        .transformAndConcat(HasClassReferences.COMBINER)
84        .toSet();
85  }
86
87  @Override
88  public Appendable write(Appendable appendable, Context context) throws IOException {
89    writeAnnotations(appendable, context);
90    writeModifiers(appendable).append(name).append('(');
91    Writables.join(", ", parameterWriters.values(), appendable, context);
92    appendable.append(") {");
93    blockWriter.write(new IndentingAppendable(appendable), context);
94    return appendable.append("}\n");
95  }
96}
97