PsiType (@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; }