private @Nullable PsiType doGetType(@Nullable PsiAnnotation stopAt) {
    PsiType type = null;
    SmartList<PsiAnnotation> annotations = new SmartList<>();
    boolean stop = false;

    for (ASTNode child = getFirstChildNode(); child != null; child = child.getTreeNext()) {
      IElementType elementType = child.getElementType();
      if (elementType == JavaElementType.ANNOTATION) {
        PsiAnnotation annotation = (PsiAnnotation)child.getPsi();
        annotations.add(annotation);
        if (annotation == stopAt) stop = true;
      }
      else if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
        assert type == null : this;
        type = new PsiClassReferenceType((PsiJavaCodeReferenceElement)child.getPsi(), null);
        if (stop) return type;
      }
      else if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(elementType)) {
        assert type == null : this;
        PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject());
        PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
        type = factory.createPrimitiveTypeFromText(child.getText()).annotate(TypeAnnotationProvider.Static.create(copy));
        if (stop) return type;
      }
      else if (elementType == JavaTokenType.LBRACKET) {
        assert type != null : this;
        PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
        type = type.createArrayType().annotate(TypeAnnotationProvider.Static.create(copy));
        if (stop) return type;
      }
      else if (elementType == JavaElementType.ANONYMOUS_CLASS) {
        PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject());
        PsiClass aClass = (PsiClass)child.getPsi();
        PsiSubstitutor substitutor = aClass instanceof PsiTypeParameter ? PsiSubstitutor.EMPTY : factory.createRawSubstitutor(aClass);
        PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
        type = factory.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass)).annotate(TypeAnnotationProvider.Static.create(copy));
        if (stop) return type;
      }
    }

    // stop == true means annotation is misplaced
    return stop ? null : type;
  }
private @Nullable PsiType doGetType(@Nullable PsiAnnotation stopAt)