public TreeElement process(TreeElement element, boolean addImports, boolean uncompleteCode) { IElementType elementType = element.getElementType(); if (elementType == JavaElementType.JAVA_CODE_REFERENCE || elementType == JavaElementType.REFERENCE_EXPRESSION) { final IElementType parentElementType = element.getTreeParent().getElementType(); if (elementType == JavaElementType.JAVA_CODE_REFERENCE || parentElementType == JavaElementType.REFERENCE_EXPRESSION || parentElementType == JavaElementType.METHOD_REF_EXPRESSION || uncompleteCode) { final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) SourceTreeToPsiMap.treeElementToPsi(element); final PsiReferenceParameterList parameterList = ref.getParameterList(); if (parameterList != null) { final PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements(); for (PsiTypeElement typeParameter : typeParameters) { process( (TreeElement) SourceTreeToPsiMap.psiElementToTree(typeParameter), addImports, uncompleteCode); } } boolean rightKind = true; if (elementType == JavaElementType.JAVA_CODE_REFERENCE) { int kind = ((PsiJavaCodeReferenceElementImpl) element).getKind(); rightKind = kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND; } if (rightKind) { boolean isInsideDocComment = TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null; boolean isShort = !((SourceJavaCodeReference) element).isQualified(); if (!makeFQ(isInsideDocComment)) { if (isShort) return element; // short name already, no need to change } PsiElement refElement; if (!uncompleteCode) { refElement = ref.resolve(); } else { PsiResolveHelper helper = JavaPsiFacade.getInstance(element.getManager().getProject()).getResolveHelper(); refElement = helper.resolveReferencedClass( ((SourceJavaCodeReference) element).getClassNameText(), SourceTreeToPsiMap.treeElementToPsi(element)); } if (refElement instanceof PsiClass) { if (makeFQ(isInsideDocComment)) { String qName = ((PsiClass) refElement).getQualifiedName(); if (qName == null) return element; PsiImportHolder file = (PsiImportHolder) SourceTreeToPsiMap.treeElementToPsi(element).getContainingFile(); if (file instanceof PsiJavaFile && ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) { if (isShort) return element; return (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); } if (file instanceof PsiJavaFile) { String thisPackageName = ((PsiJavaFile) file).getPackageName(); if (ImportHelper.hasPackage(qName, thisPackageName)) { if (!isShort) { return (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); } } } return (TreeElement) replaceReferenceWithFQ(element, (PsiClass) refElement); } else { int oldLength = element.getTextLength(); TreeElement treeElement = (TreeElement) makeShortReference( (CompositeElement) element, (PsiClass) refElement, addImports); if (treeElement.getTextLength() == oldLength && ((PsiClass) refElement).getContainingClass() != null) { PsiElement qualifier = ref.getQualifier(); if (qualifier instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) { process((TreeElement) qualifier.getNode(), addImports, uncompleteCode); } } return treeElement; } } } } } for (TreeElement child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) { child = process(child, addImports, uncompleteCode); } return element; }
@Override public ASTNode process( @NotNull ASTNode element, boolean addImports, boolean incompleteCode, boolean useFqInJavadoc, boolean useFqInCode) { IElementType elementType = element.getElementType(); if ((elementType == JavaElementType.JAVA_CODE_REFERENCE || elementType == JavaElementType.REFERENCE_EXPRESSION) && !isAnnotated(element)) { IElementType parentType = element.getTreeParent().getElementType(); if (elementType == JavaElementType.JAVA_CODE_REFERENCE || incompleteCode || parentType == JavaElementType.REFERENCE_EXPRESSION || parentType == JavaElementType.METHOD_REF_EXPRESSION) { PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) element.getPsi(); PsiReferenceParameterList parameterList = ref.getParameterList(); if (parameterList != null) { PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements(); for (PsiTypeElement typeParameter : typeParameters) { process( typeParameter.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode); } } boolean rightKind = true; if (elementType == JavaElementType.JAVA_CODE_REFERENCE) { PsiJavaCodeReferenceElementImpl impl = (PsiJavaCodeReferenceElementImpl) element; int kind = impl.getKind(impl.getContainingFile()); rightKind = kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND; } if (rightKind) { // annotations may jump out of reference (see PsiJavaCodeReferenceImpl#setAnnotations()) // so they should be processed first List<PsiAnnotation> annotations = PsiTreeUtil.getChildrenOfTypeAsList(ref, PsiAnnotation.class); for (PsiAnnotation annotation : annotations) { process(annotation.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode); } boolean isInsideDocComment = TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null; boolean isShort = !ref.isQualified(); if (isInsideDocComment ? !useFqInJavadoc : !useFqInCode) { if (isShort) return element; // short name already, no need to change } PsiElement refElement; if (!incompleteCode) { refElement = ref.resolve(); } else { PsiResolveHelper helper = JavaPsiFacade.getInstance(ref.getManager().getProject()).getResolveHelper(); final SourceJavaCodeReference reference = (SourceJavaCodeReference) element; refElement = helper.resolveReferencedClass(reference.getClassNameText(), ref); } if (refElement instanceof PsiClass) { PsiClass psiClass = (PsiClass) refElement; if (isInsideDocComment ? useFqInJavadoc : useFqInCode) { String qName = psiClass.getQualifiedName(); if (qName == null) return element; PsiFile file = ref.getContainingFile(); if (file instanceof PsiJavaFile) { if (ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) { if (isShort) return element; return makeShortReference((CompositeElement) element, psiClass, addImports); } String thisPackageName = ((PsiJavaFile) file).getPackageName(); if (ImportHelper.hasPackage(qName, thisPackageName)) { if (!isShort) { return makeShortReference((CompositeElement) element, psiClass, addImports); } } } return replaceReferenceWithFQ(element, psiClass); } else { int oldLength = element.getTextLength(); ASTNode treeElement = makeShortReference((CompositeElement) element, psiClass, addImports); if (treeElement.getTextLength() == oldLength && psiClass.getContainingClass() != null) { PsiElement qualifier = ref.getQualifier(); if (qualifier instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) { process( qualifier.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode); } } return treeElement; } } } } } for (ASTNode child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) { //noinspection AssignmentToForLoopParameter child = process(child, addImports, incompleteCode, useFqInJavadoc, useFqInCode); } return element; }