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.base.Function;
19import com.google.common.base.Joiner;
20import com.google.common.collect.FluentIterable;
21import com.google.common.collect.ImmutableList;
22import com.google.common.collect.Lists;
23import java.io.IOException;
24import java.util.Iterator;
25import java.util.List;
26import java.util.Set;
27
28public final class InterfaceWriter extends TypeWriter {
29  private final List<TypeVariableName> typeVariables;
30  InterfaceWriter(ClassName name) {
31    super(name);
32    this.typeVariables = Lists.newArrayList();
33  }
34
35  public void addTypeVariable(TypeVariableName typeVariable) {
36    this.typeVariables.add(typeVariable);
37  }
38
39  @Override
40  public Appendable write(Appendable appendable, Context context) throws IOException {
41    context = context.createSubcontext(FluentIterable.from(nestedTypeWriters)
42        .transform(new Function<TypeWriter, ClassName>() {
43          @Override public ClassName apply(TypeWriter input) {
44            return input.name;
45          }
46        })
47        .toSet());
48    writeAnnotations(appendable, context);
49    writeModifiers(appendable).append("interface ").append(name.simpleName());
50    if (!typeVariables.isEmpty()) {
51      appendable.append('<');
52      Joiner.on(", ").appendTo(appendable, typeVariables);
53      appendable.append('>');
54    }
55    Iterator<TypeName> implementedTypesIterator = implementedTypes.iterator();
56    if (implementedTypesIterator.hasNext()) {
57      appendable.append(" extends ");
58      implementedTypesIterator.next().write(appendable, context);
59      while (implementedTypesIterator.hasNext()) {
60        appendable.append(", ");
61        implementedTypesIterator.next().write(appendable, context);
62      }
63    }
64    appendable.append(" {");
65    for (MethodWriter methodWriter : methodWriters) {
66      appendable.append('\n');
67      methodWriter.write(new IndentingAppendable(appendable), context);
68    }
69    for (TypeWriter nestedTypeWriter : nestedTypeWriters) {
70      appendable.append('\n');
71      nestedTypeWriter.write(new IndentingAppendable(appendable), context);
72    }
73    appendable.append("}\n");
74    return appendable;
75  }
76
77  @Override
78  public Set<ClassName> referencedClasses() {
79    return FluentIterable.from(ImmutableList.<HasClassReferences>of())
80        .append(nestedTypeWriters)
81        .append(methodWriters)
82        .append(implementedTypes)
83        .append(annotations)
84        .transformAndConcat(HasClassReferences.COMBINER)
85        .toSet();
86  }
87}
88