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 void fillJAXBType(BasicModel fm, CtTypeReference<?> type) {

    if (type == null) {
      return;
    }
    List<CtTypeReference<?>> actualTypes = new ArrayList<CtTypeReference<?>>();
    Class<?> actualClass = type.getActualClass();
    fm.setJavaClass(actualClass);
    if (actualClass != null && Collection.class.isAssignableFrom(actualClass)) {
      fm.setCollection(true);
      List<CtTypeReference<?>> actualTypeArguments = type.getActualTypeArguments();
      if (actualTypeArguments.size() > 0) {
        actualTypes.add(actualTypeArguments.get(0));
      }
    } else if (actualClass != null && Map.class.isAssignableFrom(actualClass)) {
      fm.setMap(true);
      List<CtTypeReference<?>> actualTypeArguments = type.getActualTypeArguments();
      if (actualTypeArguments.size() == 2) {
        actualTypes = actualTypeArguments;
      }
    } else {
      actualTypes.add(type);
    }
    for (CtTypeReference<?> t : actualTypes) {
      ITypeModel processTypeReference = processTypeReference(t);
      fm.addJaxbType(processTypeReference);
    }
  }
  @Test
  public void testPrintAMethodWithGeneric() throws Exception {
    final Launcher launcher = new Launcher();
    final Factory factory = launcher.getFactory();
    factory.getEnvironment().setAutoImports(true);
    final SpoonCompiler compiler = launcher.createCompiler();
    compiler.addInputSource(new File("./src/test/java/spoon/test/prettyprinter/testclasses/"));
    compiler.build();

    final CtClass<?> aClass = (CtClass<?>) factory.Type().get(AClass.class);
    final String expected =
        "public List<? extends ArrayList> aMethodWithGeneric() {"
            + System.lineSeparator()
            + "    return new ArrayList<>();"
            + System.lineSeparator()
            + "}";
    assertEquals(expected, aClass.getMethodsByName("aMethodWithGeneric").get(0).toString());

    final CtConstructorCall<?> constructorCall =
        aClass.getElements(new TypeFilter<CtConstructorCall<?>>(CtConstructorCall.class)).get(0);
    final CtTypeReference<?> ctTypeReference =
        constructorCall.getType().getActualTypeArguments().get(0);
    assertTrue(ctTypeReference instanceof CtImplicitTypeReference);
    assertEquals("Object", ctTypeReference.getSimpleName());
  }
  public static CtMethod cloneMethodTest(CtMethod method, String suffix, int timeOut) {
    CtMethod cloned_method = cloneMethod(method, suffix);
    CtAnnotation testAnnotation =
        cloned_method
            .getAnnotations()
            .stream()
            .filter(annotation -> annotation.toString().contains("Test"))
            .findFirst()
            .orElse(null);

    if (testAnnotation != null) {
      cloned_method.removeAnnotation(testAnnotation);
    }

    testAnnotation = method.getFactory().Core().createAnnotation();
    CtTypeReference<Object> ref = method.getFactory().Core().createTypeReference();
    ref.setSimpleName("Test");

    CtPackageReference refPackage = method.getFactory().Core().createPackageReference();
    refPackage.setSimpleName("org.junit");
    ref.setPackage(refPackage);
    testAnnotation.setAnnotationType(ref);

    Map<String, Object> elementValue = new HashMap<>();
    elementValue.put("timeout", timeOut);
    testAnnotation.setElementValues(elementValue);

    cloned_method.addAnnotation(testAnnotation);

    return cloned_method;
  }
  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 void fillTypeParameters(GenericElementModel model, CtGenericElement element) {
   List<CtTypeReference<?>> ftp = element.getFormalTypeParameters();
   if (ftp == null || ftp.isEmpty()) {
     return;
   }
   for (CtTypeReference<?> param : ftp) {
     String name = param.getSimpleName();
     TypeParameterModel paramModel = new TypeParameterModel();
     paramModel.setName(name);
     model.getTypeParameters().add(paramModel);
   }
 }
  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;
  }
  /**
   * 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 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;
  }
Beispiel #10
0
 @Override
 public <C extends CtTypedElement> C setType(CtTypeReference<T> type) {
   if (type != null) {
     type.setParent(this);
   }
   this.type = type;
   return (C) this;
 }
Beispiel #11
0
 /** Actually invokes from a compile-time invocation (by using runtime reflection). */
 @SuppressWarnings("unchecked")
 public static <T> T invoke(CtInvocation<T> i)
     throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
   Object target = i.getTarget() == null ? null : ((CtLiteral<?>) i.getTarget()).getValue();
   List<Object> args = new ArrayList<Object>();
   for (CtExpression<?> e : i.getArguments()) {
     args.add(((CtLiteral<?>) e).getValue());
   }
   Class<?> c = i.getExecutable().getDeclaringType().getActualClass();
   ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>();
   for (CtTypeReference<?> type : i.getExecutable().getActualTypeArguments()) {
     argTypes.add(type.getActualClass());
   }
   return (T)
       c.getMethod(i.getExecutable().getSimpleName(), argTypes.toArray(new Class[argTypes.size()]))
           .invoke(target, args.toArray());
 }
  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;
  }
Beispiel #13
0
 @Override
 public <C extends CtExpression<T>> C addTypeCast(CtTypeReference<?> type) {
   if (typeCasts == CtElementImpl.<CtTypeReference<?>>emptyList()) {
     typeCasts = new ArrayList<CtTypeReference<?>>(CASTS_CONTAINER_DEFAULT_CAPACITY);
   }
   type.setParent(this);
   typeCasts.add(type);
   return (C) this;
 }
  protected CtVariableRead buildVarRef(CtTypeReference type, Factory factory) {
    CtTypeReference<Object> typeRef = factory.Core().clone(type);

    CtLocalVariable<Object> localVar = factory.Core().createLocalVariable();
    localVar.setType(typeRef);
    localVar.setSimpleName("var_" + type.getSimpleName() + "_" + System.currentTimeMillis());

    CtVariableReadImpl varRead = new CtVariableReadImpl();
    varRead.setVariable(factory.Code().createLocalVariableReference(localVar));
    return varRead;
  }
  private void createAssignment(CtConditional ctConditional, CtIf anIf, CtAssignment assignment) {
    CtAssignment assignmentThen = assignment.clone();
    assignmentThen.setAssignment(ctConditional.getThenExpression());
    assignmentThen.setParent(anIf);
    anIf.setThenStatement(assignmentThen);

    CtAssignment assignmentElse = assignment.clone();
    assignmentElse.setAssignment(ctConditional.getElseExpression());
    assignmentElse.setParent(anIf);
    anIf.setThenStatement(assignmentElse);

    List<CtTypeReference> typeCasts = ctConditional.getTypeCasts();
    for (int i = 0; i < typeCasts.size(); i++) {
      CtTypeReference ctTypeReference = typeCasts.get(i);
      assignmentThen.getAssignment().addTypeCast(ctTypeReference.clone());
      assignmentElse.getAssignment().addTypeCast(ctTypeReference.clone());
    }

    anIf.setElseStatement(getFactory().Code().createCtBlock(assignmentElse));
    anIf.setThenStatement(getFactory().Code().createCtBlock(assignmentThen));
  }
  protected CtLocalVariable createLocalVarFromMethodLiterals(
      CtMethod method, CtTypeReference type) {
    List<CtLiteral> literals =
        getLiterals(method)
            .stream()
            .filter(lit -> lit.getType() != null)
            .filter(lit -> lit.getType().equals(type))
            .collect(Collectors.toList());

    if (literals.isEmpty()) {
      return null;
    }

    CtLiteral lit = literals.get(AmplificationHelper.getRandom().nextInt(literals.size()));
    return type.getFactory().Code().createLocalVariable(type, "vc_" + count++, lit);
  }
  protected Statement getLocalVar(CtTypeReference type, InputContext inputContext) {
    List<Statement> list =
        localVars
            .stream()
            .filter(var -> var.getCtCodeFragment() != null)
            .filter(var -> type.equals(((CtLocalVariable) var.getCtCodeFragment()).getType()))
            .filter(
                var ->
                    inputContext.getVariableOrFieldNamed(
                            ((CtLocalVariable) var.getCtCodeFragment()).getSimpleName())
                        == null)
            .collect(Collectors.toList());

    if (list.isEmpty()) {
      return null;
    } else {
      boolean localVarFind;
      while (!list.isEmpty()) {
        Statement localVar = list.remove(AmplificationHelper.getRandom().nextInt(list.size()));
        localVarFind = true;
        for (CtVariableReference var : localVar.getInputContext().getVar()) {
          CtVariableReference<?> candidate = inputContext.candidate(var.getType(), true);
          if (candidate == null) {
            localVarFind = false;
            break;
          }
        }
        if (localVarFind) {
          Statement cloneLocalVar = localVar.clone();
          for (CtVariableReference var : localVar.getInputContext().getVar()) {
            try {
              CtVariableReference variable =
                  cloneLocalVar.getInputContext().getVariableOrFieldNamed(var.getSimpleName());
              cloneLocalVar
                  .getInputContext()
                  .getVariableOrFieldNamed(var.getSimpleName())
                  .replace(variable);
            } catch (Exception e) {
              continue;
            }
            return cloneLocalVar;
          }
        }
      }
      return null;
    }
  }
  @Override
  public void process(CtConditional ctConditional) {
    CtStatement parent = ctConditional.getParent(CtStatement.class);
    while (!(parent.getParent() instanceof CtStatementList)) {
      parent = parent.getParent(CtStatement.class);
    }
    CtExpression condition = ctConditional.getCondition();

    CtIf anIf = getFactory().Core().createIf();
    anIf.setPosition(ctConditional.getPosition());

    if (parent instanceof CtReturn) {
      if (!((CtReturn) parent).getReturnedExpression().equals(ctConditional)) {
        return;
      }

      CtReturn returnThen = (CtReturn) parent.clone();
      CtReturn returnElse = (CtReturn) parent.clone();

      returnThen.setReturnedExpression(ctConditional.getThenExpression());
      returnElse.setReturnedExpression(ctConditional.getElseExpression());

      List<CtTypeReference> typeCasts = ctConditional.getTypeCasts();
      for (int i = 0; i < typeCasts.size(); i++) {
        CtTypeReference ctTypeReference = typeCasts.get(i);
        returnThen.getReturnedExpression().addTypeCast(ctTypeReference.clone());
        returnElse.getReturnedExpression().addTypeCast(ctTypeReference.clone());
      }

      anIf.setElseStatement(getFactory().Code().createCtBlock(returnElse));
      anIf.setThenStatement(getFactory().Code().createCtBlock(returnThen));
    } else if (parent instanceof CtAssignment) {
      CtAssignment assignment = (CtAssignment) parent;
      CtExpression ctExpression = assignment.getAssignment();
      if (!ctExpression.equals(ctConditional)) {
        if (ctExpression instanceof CtBinaryOperator) {
          CtBinaryOperator ctBinaryOperator = (CtBinaryOperator) ctExpression;

          createAssignment(ctConditional, anIf, assignment);
          CtBinaryOperator cloneThen = ctBinaryOperator.clone();
          CtBinaryOperator cloneElse = ctBinaryOperator.clone();

          if (ctBinaryOperator.getLeftHandOperand().equals(ctConditional)) {
            cloneThen.setLeftHandOperand(ctConditional.getThenExpression());
            ctConditional.getThenExpression().setParent(cloneThen);
            cloneElse.setLeftHandOperand(ctConditional.getElseExpression());
          } else if (ctBinaryOperator.getRightHandOperand().equals(ctConditional)) {
            cloneThen.setRightHandOperand(ctConditional.getThenExpression());
            cloneElse.setRightHandOperand(ctConditional.getElseExpression());
          }

          cloneThen.getLeftHandOperand().setParent(cloneThen);
          cloneElse.getLeftHandOperand().setParent(cloneElse);
          ((CtAssignment) ((CtBlock) anIf.getThenStatement()).getStatement(0))
              .setAssignment(cloneThen);
          ((CtAssignment) ((CtBlock) anIf.getElseStatement()).getStatement(0))
              .setAssignment(cloneElse);
        } else {
          return;
        }
      } else {
        createAssignment(ctConditional, anIf, assignment);
      }
    } else if (parent instanceof CtLocalVariable) {
      CtLocalVariable localVariable = (CtLocalVariable) parent;
      if (!localVariable.getDefaultExpression().equals(ctConditional)) {
        return;
      }

      CtLocalVariable clone = localVariable.clone();
      clone.setDefaultExpression(null);

      localVariable.insertBefore(clone);

      CtAssignment variableAssignment =
          getFactory()
              .Code()
              .createVariableAssignment(localVariable.getReference(), false, ctConditional);
      variableAssignment.setType(localVariable.getType().clone());
      variableAssignment.setPosition(ctConditional.getPosition());
      createAssignment(ctConditional, anIf, variableAssignment);
    } else if (parent instanceof CtInvocation) {
      CtInvocation invocation = (CtInvocation) parent;
      CtInvocation cloneThen = invocation.clone();
      CtInvocation cloneElse = invocation.clone();

      List arguments = cloneThen.getArguments();
      boolean found = false;
      for (int i = 0; i < arguments.size(); i++) {
        Object o = arguments.get(i);
        if (o.equals(ctConditional)) {
          ctConditional.getThenExpression().setParent(invocation);
          arguments.set(i, ctConditional.getThenExpression());
          ctConditional.getElseExpression().setParent(invocation);
          cloneElse.getArguments().set(i, ctConditional.getElseExpression());
          found = true;
          break;
        }
      }
      if (!found) {
        return;
      }

      cloneThen.setParent(anIf);
      cloneElse.setParent(anIf);

      anIf.setElseStatement(getFactory().Code().createCtBlock(cloneElse));
      anIf.setThenStatement(getFactory().Code().createCtBlock(cloneThen));
    } else if (parent instanceof CtConstructorCall) {
      CtConstructorCall invocation = (CtConstructorCall) parent;
      CtConstructorCall cloneThen = invocation.clone();
      CtConstructorCall cloneElse = invocation.clone();

      List arguments = cloneThen.getArguments();
      boolean found = false;
      for (int i = 0; i < arguments.size(); i++) {
        Object o = arguments.get(i);
        if (o.equals(ctConditional)) {
          arguments.set(i, ctConditional.getThenExpression());
          cloneElse.getArguments().set(i, ctConditional.getElseExpression());
          found = true;
          break;
        }
      }
      if (!found) {
        return;
      }

      cloneThen.setParent(anIf);
      cloneElse.setParent(anIf);

      anIf.setElseStatement(getFactory().Code().createCtBlock(cloneElse));
      anIf.setThenStatement(getFactory().Code().createCtBlock(cloneThen));
    } else if (parent instanceof CtIf) {
      CtIf elem = (CtIf) parent;
      if (!elem.getCondition().equals(ctConditional)) {
        return;
      }

      CtIf cloneThen = elem.clone();
      cloneThen.setParent(anIf);
      CtIf cloneElse = elem.clone();
      cloneElse.setParent(anIf);

      cloneThen.setCondition(ctConditional.getThenExpression());
      ctConditional.getThenExpression().setParent(cloneThen);

      cloneElse.setCondition(ctConditional.getElseExpression());
      ctConditional.getElseExpression().setParent(cloneElse);

      anIf.setElseStatement(getFactory().Code().createCtBlock(cloneElse));
      anIf.setThenStatement(getFactory().Code().createCtBlock(cloneThen));
    } else if (parent instanceof CtThrow) {
      return;
    } else if (parent instanceof CtLoop) {
      return;
    } else if (parent instanceof CtUnaryOperator) {
      return;
    } else {
      System.err.println(parent);
      throw new RuntimeException("Other " + parent.getClass());
    }
    /*if(ctConditional.getThenExpression().getTypeCasts() == null ||
            ctConditional.getThenExpression().getTypeCasts().isEmpty()) {
        ((CtExpression)anIf.getThenStatement()).setTypeCasts(ctConditional.getTypeCasts());
    }
    if(ctConditional.getElseExpression().getTypeCasts() == null ||
            ctConditional.getElseExpression().getTypeCasts().isEmpty()) {
        ((CtExpression) anIf.getElseStatement())
                .setTypeCasts(ctConditional.getTypeCasts());
    }*/
    anIf.setCondition(condition);
    condition.setParent(anIf);
    parent.replace(anIf);
  }
Beispiel #19
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;
  }