Package net.java.quickcheck.srcgenerator

Source Code of net.java.quickcheck.srcgenerator.Method

/*
*  Licensed to the author under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package net.java.quickcheck.srcgenerator;

import static java.lang.String.*;
import static javax.lang.model.element.ElementKind.*;
import static net.java.quickcheck.srcgenerator.Assertion.*;
import static net.java.quickcheck.srcgenerator.Parameter.Cardinality.*;
import static net.java.quickcheck.srcgenerator.Traversal.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.annotation.processing.Messager;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.NoType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.tools.Diagnostic.Kind;

import net.java.quickcheck.srcgenerator.Parameter.Cardinality;

class Method{
 
  final String name;
  final Type returnType;
  final List<Parameter> parameters = new ArrayList<Parameter>();
  final List<TypeParameter> typeParameters = new ArrayList<TypeParameter>();
  private final Messager messager;
  static final String GENERATOR_TYPE_NAME = "net.java.quickcheck.Generator";
 
  Method(CharSequence name, CharSequence returnType, Parameter... parameters){
    this(name, returnType, Collections.<TypeParameter> emptyList(), Arrays.asList(parameters), false);
  }
 
  Method(CharSequence name, CharSequence returnType, List<TypeParameter> typeParameters, List<Parameter> parameters,
      boolean generic) {
    assertNotNull(name, "name");
    assertNotNull(returnType, "returnType");
    assertNotNull(typeParameters, "typeParameters");
    assertNotNull(parameters, "parameters");
    assertNotNull(generic, "generic");
    this.messager = null;
    this.name = name.toString();
    this.returnType = new Type(returnType, generic);
    this.typeParameters.addAll(typeParameters);
    this.parameters.addAll(parameters);
  }

  Method(Messager messager, ExecutableElement method) {
    assertNotNull(messager, "messager");
    this.messager = messager;
    this.messager.printMessage(Kind.NOTE, format("Start method %s",method));
    parameters.addAll(parameters(method));
    this.name = method.getSimpleName().toString();
    this.returnType = returnTypeName(method);
    for(TypeParameterElement t : method.getTypeParameters()) this.typeParameters.add(new TypeParameter(t));
  }

  private List<Parameter> parameters(ExecutableElement method) {
    List<Parameter> ps = new ArrayList<Parameter>();
    for(int i=0;i<method.getParameters().size();i++) {
      final VariableElement v = method.getParameters().get(i);
      final Cardinality cardinality = method.getParameters().size() - 1 == i ? VARARRAY : ARRAY;
      ps.add(new Parameter(v, cardinality));
    }
    return ps;
  }

  private Type returnTypeName(ExecutableElement method) {
    verifyReturnType(method);
    List<? extends TypeMirror> typeArguments = toDeclaredType(method.getReturnType()).getTypeArguments();
    assertTrue(typeArguments.size() > 0, "type argument expected");
    //TODO would have to look for the type parameter otherwise
    TypeMirror next = typeArguments.get(typeArguments.size() - 1)
    return new Type(next.toString(), next instanceof TypeVariable);
  }

  private void verifyReturnType(ExecutableElement method) {
    TypeMirror type = method.getReturnType();
    assertTrue(isSubtypeOfGenerator(type), "The return type [%s] is not an implementation of %s.",
        method, GENERATOR_TYPE_NAME);
    assertTrue(isInterface(type), "The return type (%s) has to be an interface.", type);
  }

  private boolean isInterface(TypeMirror typeMirror) {
    return toTypeElement(typeMirror).getKind() == INTERFACE;
  }
 
  private boolean isSubtypeOfGenerator(TypeMirror type) {
    if(type instanceof NoType) return false;
    if(toTypeElement(type).getQualifiedName().contentEquals(GENERATOR_TYPE_NAME)) return true;
    for(TypeMirror t : toTypeElement(type).getInterfaces()){
      if(isSubtypeOfGenerator(t)) return true;
    }
    return false;
  }

  @Override
  public boolean equals(Object other) {
    if(!(other instanceof Method)) return false;
    Method method = (Method) other;
    return method.name.equals(name) && method.returnType.equals(returnType) && method.parameters.equals(parameters)
        && method.typeParameters.equals(typeParameters);
  }
 
  @Override
  public int hashCode() {
    return name.hashCode();
  }
 
  @Override
  public String toString() {
    return format("Method[name=%s, returnType=%s, typeParameter=%s,parameters=%s]", name, returnType,
        typeParameters, parameters);
  }
}
TOP

Related Classes of net.java.quickcheck.srcgenerator.Method

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.