/**
   * Type of the benchmarks method for this snippet. This is 'void' by default.
   *
   * <p>The benchmark method type must be the same that the one
   */
  public String getBenchMethodReturnType() {
    if (benchMethodReturnType == null) {
      if (astElement != null) {
        List<CtReturn> rets = astElement.getElements(new TypeFilter<CtReturn>(CtReturn.class));
        if (rets != null && rets.size() > 0 && rets.get(0).getReturnedExpression() != null) {
          CtTypeReference t = rets.get(0).getReturnedExpression().getType();
          if (t.isAnonymous() || t.getQualifiedName().equals("<nulltype>"))
            benchMethodReturnType = "Object";
          else benchMethodReturnType = t.getQualifiedName();
        }
      }
    }

    return benchMethodReturnType == null ? "void" : benchMethodReturnType;
  }
  private ITypeModel processTypeReference(CtTypeReference<?> typeReference) {
    String qualifiedName = typeReference.getQualifiedName();
    ITypeModel existingType = registry.getType(qualifiedName);
    if (existingType != null) {
      return new ProxyType(registry, qualifiedName);
    }

    CtClass<Object> ctClass = factory.Class().get(qualifiedName);
    if (ctClass != null) {
      return processType(ctClass);
    }

    CtType<Object> ctType = factory.Type().get(qualifiedName);
    if (ctType != null) {
      return processType(ctType);
    }

    TypeModel type = new TypeModel();
    type.setFullyQualifiedName(qualifiedName);
    registry.registerType(type);

    fillReference(type, typeReference);

    Collection<CtExecutableReference<?>> methods = typeReference.getDeclaredExecutables();
    for (CtExecutableReference<?> m : methods) {
      IMethodModel methodModel = processMethodReference(m);
      type.addMethod(methodModel);
    }
    Collection<CtFieldReference<?>> fields = typeReference.getDeclaredFields();
    for (CtFieldReference<?> m : fields) {
      IFieldModel methodModel = processFieldReference(m);
      type.addField(methodModel);
    }
    return new ProxyType(registry, qualifiedName);
  }
  private IMethodModel processMethod(CtMethod<?> m, TypeModel ownerType) {

    MethodModel methodModel = new MethodModel();
    fillBasic(methodModel, m);
    fillTypeParameters(methodModel, m);
    CtTypeReference<?> returnedType = m.getType();
    ITypeModel returnedTypeModel = processTypeReference(returnedType);
    methodModel.setReturnedType(returnedTypeModel);
    fillJAXBType(methodModel, returnedType);

    List<CtParameter<?>> parameters = m.getParameters();
    for (CtParameter<?> p : parameters) {
      IParameterModel parameterModel = processParameter(p);
      methodModel.addParameter(parameterModel);
    }
    String returnedTypeSimpleName = returnedType.getSimpleName();
    String returnedTypeQualifiedname = returnedType.getQualifiedName();
    if (returnedTypeSimpleName.equalsIgnoreCase(returnedTypeQualifiedname)) {
      for (ITypeParameter tp : ownerType.getTypeParameters()) {
        if (returnedType.getSimpleName().equals(tp.getName())) {
          methodModel.setHasGenericReturnType(true);
        }
      }
      for (ITypeParameter tp : methodModel.getTypeParameters()) {
        if (returnedType.getSimpleName().equals(tp.getName())) {
          methodModel.setHasGenericReturnType(true);
        }
      }
    }
    return methodModel;
  }
  private IParameterModel processParameterReference(CtTypeReference<?> paramTypeReference) {

    ParameterModel parameterModel = new ParameterModel();
    parameterModel.setType(paramTypeReference.getQualifiedName());
    parameterModel.setName(paramTypeReference.getSimpleName());
    parameterModel.setRequired(paramTypeReference.isPrimitive());

    List<Annotation> annotations = paramTypeReference.getAnnotations();
    for (Annotation a : annotations) {
      IAnnotationModel annotationModel = processJavaLangAnnotation(a);
      parameterModel.addAnnotation(annotationModel);
    }

    return parameterModel;
  }
  private IParameterModel processParameter(CtParameter<?> paramElement) {

    ParameterModel parameterModel = new ParameterModel();

    CtTypeReference<?> paramType = paramElement.getType();
    String qualifiedName = paramType.getQualifiedName();
    parameterModel.setType(qualifiedName);
    parameterModel.setRequired(paramType.isPrimitive());

    fillBasic(parameterModel, paramElement);
    fillJAXBType(parameterModel, paramType);
    processTypeReference(paramType);

    return parameterModel;
  }
  private IFieldModel processField(CtField<?> m, TypeModel ownerType) {
    FieldModel fm = new FieldModel();
    fillBasic(fm, m);
    CtTypeReference<?> type = m.getType();
    fillJAXBType(fm, type);

    String typeSimpleName = type.getSimpleName();
    String typeQualifiedname = type.getQualifiedName();
    if (typeSimpleName.equalsIgnoreCase(typeQualifiedname)) {
      for (ITypeParameter tp : ownerType.getTypeParameters()) {
        if (typeSimpleName.equals(tp.getName())) {
          fm.setGeneric(true);
        }
      }
    }
    return fm;
  }
Exemplo n.º 7
0
  @SuppressWarnings("unchecked")
  private <T, U extends CtVariable<T>> U getVariableDeclaration(
      final String name, final Class<U> clazz) {
    final CoreFactory coreFactory = jdtTreeBuilder.getFactory().Core();
    final TypeFactory typeFactory = jdtTreeBuilder.getFactory().Type();
    final ClassFactory classFactory = jdtTreeBuilder.getFactory().Class();
    final InterfaceFactory interfaceFactory = jdtTreeBuilder.getFactory().Interface();
    final FieldFactory fieldFactory = jdtTreeBuilder.getFactory().Field();
    final ReferenceBuilder referenceBuilder = jdtTreeBuilder.getReferencesBuilder();
    final Environment environment = jdtTreeBuilder.getFactory().getEnvironment();
    // there is some extra work to do if we are looking for CtFields (and subclasses)
    final boolean lookingForFields =
        clazz == null || coreFactory.createField().getClass().isAssignableFrom(clazz);

    // try to find the variable on stack beginning with the most recent element
    for (final ASTPair astPair : stack) {
      // the variable may have been declared directly by one of these elements
      final ScopeRespectingVariableScanner<U> scanner =
          new ScopeRespectingVariableScanner(name, clazz);
      astPair.element.accept(scanner);
      if (scanner.getResult() != null) {
        return scanner.getResult();
      }

      // the variable may have been declared in a super class/interface
      if (lookingForFields && astPair.node instanceof TypeDeclaration) {
        final TypeDeclaration nodeDeclaration = (TypeDeclaration) astPair.node;
        final Deque<ReferenceBinding> referenceBindings = new ArrayDeque<>();
        // add super class if any
        if (nodeDeclaration.superclass != null
            && nodeDeclaration.superclass.resolvedType instanceof ReferenceBinding) {
          referenceBindings.push((ReferenceBinding) nodeDeclaration.superclass.resolvedType);
        }
        // add interfaces if any
        if (nodeDeclaration.superInterfaces != null) {
          for (final TypeReference tr : nodeDeclaration.superInterfaces) {
            if (tr.resolvedType instanceof ReferenceBinding) {
              referenceBindings.push((ReferenceBinding) tr.resolvedType);
            }
          }
        }

        while (!referenceBindings.isEmpty()) {
          final ReferenceBinding referenceBinding = referenceBindings.pop();
          for (final FieldBinding fieldBinding : referenceBinding.fields()) {
            if (name.equals(new String(fieldBinding.readableName()))) {
              final String qualifiedNameOfParent = new String(referenceBinding.readableName());
              final CtType parentOfField =
                  referenceBinding.isClass()
                      ? classFactory.create(qualifiedNameOfParent)
                      : interfaceFactory.create(qualifiedNameOfParent);
              return (U)
                  fieldFactory.create(
                      parentOfField,
                      JDTTreeBuilderQuery.getModifiers(fieldBinding.modifiers),
                      referenceBuilder.getTypeReference(fieldBinding.type),
                      name);
            }
          }
          // add super class if any
          final ReferenceBinding superclass = referenceBinding.superclass();
          if (superclass != null) {
            referenceBindings.push(superclass);
          }
          // add interfaces if any
          final ReferenceBinding[] interfaces = referenceBinding.superInterfaces();
          if (interfaces != null) {
            for (ReferenceBinding rb : interfaces) {
              referenceBindings.push(rb);
            }
          }
        }
      }
    }

    // the variable may have been imported statically from another class/interface
    if (lookingForFields) {
      final CtReference potentialReferenceToField =
          referenceBuilder.getDeclaringReferenceFromImports(name.toCharArray());
      if (potentialReferenceToField != null
          && potentialReferenceToField instanceof CtTypeReference) {
        final CtTypeReference typeReference = (CtTypeReference) potentialReferenceToField;
        try {
          final Class classOfType = typeReference.getActualClass();
          if (classOfType != null) {
            final CtType declaringTypeOfField =
                typeReference.isInterface()
                    ? interfaceFactory.get(classOfType)
                    : classFactory.get(classOfType);
            final CtField field = declaringTypeOfField.getField(name);
            if (field != null) {
              return (U) field;
            }
          }
        } catch (final SpoonClassNotFoundException scnfe) {
          // in noclasspath mode we do some heuristics to determine if `name` could be a
          // field that has been imported statically from another class (or interface).
          if (environment.getNoClasspath()) {
            // if `potentialReferenceToField` is a `CtTypeReference` then `name` must
            // have been imported statically. Otherwise, `potentialReferenceToField`
            // would be a CtPackageReference!

            // if `name` consists only of upper case characters separated by '_', we
            // assume a constant value according to JLS.
            if (name.toUpperCase().equals(name)) {
              final CtType parentOfField = classFactory.create(typeReference.getQualifiedName());
              // it is the best thing we can do
              final CtField field = coreFactory.createField();
              field.setParent(parentOfField);
              field.setSimpleName(name);
              // it is the best thing we can do
              field.setType(typeFactory.nullType());
              return (U) field;
            }
          }
        }
      }
    }

    return null;
  }