Home | History | Annotate | Download | only in writer
      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.base.Optional;
     19 import com.google.common.collect.FluentIterable;
     20 import com.google.common.collect.ImmutableList;
     21 import com.google.common.collect.Iterables;
     22 import com.google.common.collect.Lists;
     23 import com.google.common.collect.Maps;
     24 import java.io.IOException;
     25 import java.util.List;
     26 import java.util.Map;
     27 import java.util.Set;
     28 import javax.lang.model.element.TypeElement;
     29 
     30 import static com.google.common.base.Preconditions.checkArgument;
     31 
     32 public final class MethodWriter extends Modifiable implements HasClassReferences, Writable {
     33   private final TypeName returnType;
     34   private final String name;
     35   private final Map<String, VariableWriter> parameterWriters;
     36   private final List<TypeVariableName> typeParameters;
     37   private Optional<BlockWriter> body;
     38 
     39   MethodWriter(TypeName returnType, String name) {
     40     this.returnType = returnType;
     41     this.name = name;
     42     this.parameterWriters = Maps.newLinkedHashMap();
     43     this.typeParameters = Lists.newArrayList();
     44     this.body = Optional.absent();
     45   }
     46 
     47   public String name() {
     48     return name;
     49   }
     50 
     51   public TypeName returnType() {
     52     return returnType;
     53   }
     54 
     55   public void addTypeParameter(TypeVariableName typeVariableName) {
     56     this.typeParameters.add(typeVariableName);
     57   }
     58 
     59   public void addTypeParameters(Iterable<TypeVariableName> typeVariableNames) {
     60     Iterables.addAll(typeParameters, typeVariableNames);
     61   }
     62 
     63   public VariableWriter addParameter(Class<?> type, String name) {
     64     return addParameter(ClassName.fromClass(type), name);
     65   }
     66 
     67   public VariableWriter addParameter(TypeElement type, String name) {
     68     return addParameter(ClassName.fromTypeElement(type), name);
     69   }
     70 
     71   public VariableWriter addParameter(TypeWriter type, String name) {
     72     return addParameter(type.name, name);
     73   }
     74 
     75   public VariableWriter addParameter(TypeName type, String name) {
     76     checkArgument(!parameterWriters.containsKey(name));
     77     VariableWriter parameterWriter = new VariableWriter(type, name);
     78     parameterWriters.put(name, parameterWriter);
     79     return parameterWriter;
     80   }
     81 
     82   public BlockWriter body() {
     83     if (body.isPresent()) {
     84       return body.get();
     85     } else {
     86       BlockWriter blockWriter = new BlockWriter();
     87       body = Optional.of(blockWriter);
     88       return blockWriter;
     89     }
     90   }
     91 
     92   @Override
     93   public Appendable write(Appendable appendable, Context context) throws IOException {
     94     writeAnnotations(appendable, context);
     95     writeModifiers(appendable);
     96     Writables.join(", ", typeParameters, "<", "> ", appendable, context);
     97     returnType.write(appendable, context);
     98     appendable.append(' ').append(name).append('(');
     99     Writables.join(", ", parameterWriters.values(), appendable, context);
    100     appendable.append(")");
    101     if (body.isPresent()) {
    102       appendable.append(" {");
    103       body.get().write(new IndentingAppendable(appendable), context);
    104       appendable.append("}\n");
    105     } else {
    106       appendable.append(";\n");
    107     }
    108     return appendable;
    109   }
    110 
    111   @Override
    112   public Set<ClassName> referencedClasses() {
    113     return FluentIterable.from(ImmutableList.<HasClassReferences>of())
    114         .append(parameterWriters.values())
    115         .append(returnType)
    116         .append(body.asSet())
    117         .append(annotations)
    118         .transformAndConcat(HasClassReferences.COMBINER)
    119         .toSet();
    120   }
    121 }
    122