public static int insertClassReference( PsiClass psiClass, PsiFile file, int startOffset, int endOffset) { final Project project = file.getProject(); PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); documentManager.commitAllDocuments(); final PsiManager manager = file.getManager(); final Document document = FileDocumentManager.getInstance().getDocument(file.getViewProvider().getVirtualFile()); final PsiReference reference = file.findReferenceAt(startOffset); if (reference != null) { final PsiElement resolved = reference.resolve(); if (resolved instanceof PsiClass) { if (((PsiClass) resolved).getQualifiedName() == null || manager.areElementsEquivalent(psiClass, resolved)) { return endOffset; } } } String name = psiClass.getName(); if (name == null) { return endOffset; } assert document != null; document.replaceString(startOffset, endOffset, name); int newEndOffset = startOffset + name.length(); final RangeMarker toDelete = insertTemporary(newEndOffset, document, " "); documentManager.commitAllDocuments(); PsiElement element = file.findElementAt(startOffset); if (element instanceof PsiIdentifier) { PsiElement parent = element.getParent(); if (parent instanceof PsiJavaCodeReferenceElement && !((PsiJavaCodeReferenceElement) parent).isQualified() && !(parent.getParent() instanceof PsiPackageStatement)) { PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) parent; if (psiClass.isValid() && !psiClass.getManager().areElementsEquivalent(psiClass, resolveReference(ref))) { final boolean staticImport = ref instanceof PsiImportStaticReferenceElement; PsiElement newElement; try { newElement = staticImport ? ((PsiImportStaticReferenceElement) ref).bindToTargetClass(psiClass) : ref.bindToElement(psiClass); } catch (IncorrectOperationException e) { return endOffset; // can happen if fqn contains reserved words, for example } final RangeMarker rangeMarker = document.createRangeMarker(newElement.getTextRange()); documentManager.doPostponedOperationsAndUnblockDocument(document); documentManager.commitDocument(document); newElement = CodeInsightUtilCore.findElementInRange( file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), PsiJavaCodeReferenceElement.class, JavaLanguage.INSTANCE); rangeMarker.dispose(); if (newElement != null) { newEndOffset = newElement.getTextRange().getEndOffset(); if (!(newElement instanceof PsiReferenceExpression)) { PsiReferenceParameterList parameterList = ((PsiJavaCodeReferenceElement) newElement).getParameterList(); if (parameterList != null) { newEndOffset = parameterList.getTextRange().getStartOffset(); } } if (!staticImport && !psiClass .getManager() .areElementsEquivalent(psiClass, resolveReference((PsiReference) newElement)) && !PsiUtil.isInnerClass(psiClass)) { final String qName = psiClass.getQualifiedName(); if (qName != null) { document.replaceString( newElement.getTextRange().getStartOffset(), newEndOffset, qName); newEndOffset = newElement.getTextRange().getStartOffset() + qName.length(); } } } } } } if (toDelete.isValid()) { document.deleteString(toDelete.getStartOffset(), toDelete.getEndOffset()); } return newEndOffset; }
public static String checkMethodReferenceContext( PsiMethodReferenceExpression methodRef, PsiElement resolve, PsiType functionalInterfaceType) { final PsiClass containingClass = resolve instanceof PsiMethod ? ((PsiMethod) resolve).getContainingClass() : (PsiClass) resolve; final boolean isStaticSelector = isStaticallyReferenced(methodRef); final PsiElement qualifier = methodRef.getQualifier(); boolean isMethodStatic = false; boolean receiverReferenced = false; boolean isConstructor = true; if (resolve instanceof PsiMethod) { final PsiMethod method = (PsiMethod) resolve; isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC); isConstructor = method.isConstructor(); receiverReferenced = hasReceiver(methodRef, method, functionalInterfaceType); if (method.hasModifierProperty(PsiModifier.ABSTRACT) && qualifier instanceof PsiSuperExpression) { return "Abstract method '" + method.getName() + "' cannot be accessed directly"; } } if (!receiverReferenced && isStaticSelector && !isMethodStatic && !isConstructor) { return "Non-static method cannot be referenced from a static context"; } if (!receiverReferenced && !isStaticSelector && isMethodStatic) { return "Static method referenced through non-static qualifier"; } if (receiverReferenced && isStaticSelector && isMethodStatic && !isConstructor) { return "Static method referenced through receiver"; } if (isMethodStatic && isStaticSelector && qualifier instanceof PsiTypeElement) { final PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.getChildOfType(qualifier, PsiJavaCodeReferenceElement.class); if (referenceElement != null) { final PsiReferenceParameterList parameterList = referenceElement.getParameterList(); if (parameterList != null && parameterList.getTypeArguments().length > 0) { return "Parameterized qualifier on static method reference"; } } } if (isConstructor) { if (containingClass != null && PsiUtil.isInnerClass(containingClass) && containingClass.isPhysical()) { PsiClass outerClass = containingClass.getContainingClass(); if (outerClass != null && !InheritanceUtil.hasEnclosingInstanceInScope(outerClass, methodRef, true, false)) { return "An enclosing instance of type " + PsiFormatUtil.formatClass(outerClass, PsiFormatUtilBase.SHOW_NAME) + " is not in scope"; } } } return null; }