@Nullable public static String getReferencePrefix(@NotNull PsiElement insertedElement, int offsetInFile) { final PsiReference ref = insertedElement.getContainingFile().findReferenceAt(offsetInFile); if (ref != null) { final PsiElement element = ref.getElement(); final int endIndex = offsetInFile - element.getTextRange().getStartOffset(); final int beginIndex = ref.getRangeInElement().getStartOffset(); if (beginIndex > endIndex) { LOG.error( "Inconsistent reference (found at offset not included in its range): ref=" + ref + " element=" + element + " text=" + element.getText()); } if (beginIndex < 0) { LOG.error( "Inconsistent reference (begin < 0): ref=" + ref + " element=" + element + "; begin=" + beginIndex + " text=" + element.getText()); } LOG.assertTrue(endIndex >= 0); return element.getText().substring(beginIndex, endIndex); } return null; }
public static boolean addResult( Processor<UsageInfo> results, PsiReference ref, FindUsagesOptions options) { if (filterUsage(ref.getElement(), options)) { TextRange rangeInElement = ref.getRangeInElement(); return results.process( new UsageInfo( ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false)); } return true; }
@Override @Nullable public PsiReference findReferenceAt(int offset) { TextRange minRange = new TextRange(0, getContents().length()); PsiReference ret = null; for (final Language language : getLanguages()) { final PsiElement psiRoot = getPsi(language); final PsiReference reference = SharedPsiElementImplUtil.findReferenceAt(psiRoot, offset, language); if (reference == null) continue; final TextRange textRange = reference .getRangeInElement() .shiftRight(reference.getElement().getTextRange().getStartOffset()); if (minRange.contains(textRange) && !textRange.contains(minRange)) { minRange = textRange; ret = reference; } } return ret; }
public static void visitRefInDocTag( final PsiDocTag tag, final JavadocManager manager, final PsiElement context, final ArrayList<ProblemDescriptor> problems, final InspectionManager inspectionManager, final boolean onTheFly) { final String tagName = tag.getName(); final PsiDocTagValue value = tag.getValueElement(); if (value == null) return; final JavadocTagInfo info = manager.getTagInfo(tagName); if (info != null && !info.isValidInContext(context)) return; final String message = info == null || !info.isInline() ? null : info.checkTagValue(value); if (message != null) { problems.add(createDescriptor(value, message, inspectionManager, onTheFly)); } final PsiReference reference = value.getReference(); if (reference == null) return; final PsiElement element = reference.resolve(); if (element != null) return; final int textOffset = value.getTextOffset(); if (textOffset == value.getTextRange().getEndOffset()) return; final PsiDocTagValue valueElement = tag.getValueElement(); if (valueElement == null) return; final CharSequence paramName = value .getContainingFile() .getViewProvider() .getContents() .subSequence(textOffset, value.getTextRange().getEndOffset()); final String params = "<code>" + paramName + "</code>"; final List<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>(); if (onTheFly && "param".equals(tagName)) { final PsiDocCommentOwner commentOwner = PsiTreeUtil.getParentOfType(tag, PsiDocCommentOwner.class); if (commentOwner instanceof PsiMethod) { final PsiMethod method = (PsiMethod) commentOwner; final PsiParameter[] parameters = method.getParameterList().getParameters(); final PsiDocTag[] tags = tag.getContainingComment().getTags(); final Set<String> unboundParams = new HashSet<String>(); for (PsiParameter parameter : parameters) { if (!JavaDocLocalInspection.isFound(tags, parameter)) { unboundParams.add(parameter.getName()); } } if (!unboundParams.isEmpty()) { fixes.add(new RenameReferenceQuickFix(unboundParams)); } } } fixes.add(new RemoveTagFix(tagName, paramName)); problems.add( inspectionManager.createProblemDescriptor( valueElement, reference.getRangeInElement(), cannotResolveSymbolMessage(params), ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, onTheFly, fixes.toArray(new LocalQuickFix[fixes.size()]))); }
@Override public void visitXmlAttributeValue(XmlAttributeValue value) { for (PsiReference reference : value.getReferences()) { if (!(reference instanceof OnClickConverter.MyReference)) { continue; } final OnClickConverter.MyReference ref = (OnClickConverter.MyReference) reference; final String methodName = ref.getValue(); if (methodName.isEmpty()) { continue; } final ResolveResult[] results = ref.multiResolve(false); final Set<PsiClass> resolvedClasses = new HashSet<PsiClass>(); final Set<PsiClass> resolvedClassesWithMistake = new HashSet<PsiClass>(); for (ResolveResult result : results) { if (result instanceof OnClickConverter.MyResolveResult) { final PsiElement element = result.getElement(); if (element != null) { final PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class); if (aClass != null) { resolvedClasses.add(aClass); if (!((OnClickConverter.MyResolveResult) result).hasCorrectSignature()) { resolvedClassesWithMistake.add(aClass); } } } } } PsiClass activity = null; for (PsiClass relatedActivity : myRelatedActivities) { if (!containsOrExtends(resolvedClasses, relatedActivity)) { activity = relatedActivity; break; } else if (activity == null && containsOrExtends(resolvedClassesWithMistake, relatedActivity)) { activity = relatedActivity; } } if (activity != null) { reportMissingOnClickProblem( ref, activity, methodName, resolvedClassesWithMistake.contains(activity)); } else if (results.length == 0) { myResult.add( myInspectionManager.createProblemDescriptor( value, reference.getRangeInElement(), ProblemsHolder.unresolvedReferenceMessage(reference), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, myOnTheFly)); } else if (resolvedClassesWithMistake.size() > 0) { reportMissingOnClickProblem( ref, resolvedClassesWithMistake.iterator().next(), methodName, true); } } }
@NotNull public static UsageInfo[] findUsages( final PsiElement element, final String newName, boolean searchInStringsAndComments, boolean searchForTextOccurrences, Map<? extends PsiElement, String> allRenames) { final List<UsageInfo> result = Collections.synchronizedList(new ArrayList<UsageInfo>()); PsiManager manager = element.getManager(); GlobalSearchScope projectScope = GlobalSearchScope.projectScope(manager.getProject()); RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(element); Collection<PsiReference> refs = processor.findReferences(element, searchInStringsAndComments); for (final PsiReference ref : refs) { if (ref == null) { LOG.error("null reference from processor " + processor); continue; } PsiElement referenceElement = ref.getElement(); result.add( new MoveRenameUsageInfo( referenceElement, ref, ref.getRangeInElement().getStartOffset(), ref.getRangeInElement().getEndOffset(), element, ref.resolve() == null)); } processor.findCollisions(element, newName, allRenames, result); final PsiElement searchForInComments = processor.getElementToSearchInStringsAndComments(element); if (searchInStringsAndComments && searchForInComments != null) { String stringToSearch = ElementDescriptionUtil.getElementDescription( searchForInComments, NonCodeSearchDescriptionLocation.STRINGS_AND_COMMENTS); if (stringToSearch.length() > 0) { final String stringToReplace = getStringToReplace(element, newName, false, processor); TextOccurrencesUtil.UsageInfoFactory factory = new NonCodeUsageInfoFactory(searchForInComments, stringToReplace); TextOccurrencesUtil.addUsagesInStringsAndComments( searchForInComments, stringToSearch, result, factory); } } if (searchForTextOccurrences && searchForInComments != null) { String stringToSearch = ElementDescriptionUtil.getElementDescription( searchForInComments, NonCodeSearchDescriptionLocation.NON_JAVA); if (stringToSearch.length() > 0) { final String stringToReplace = getStringToReplace(element, newName, true, processor); addTextOccurrence( searchForInComments, result, projectScope, stringToSearch, stringToReplace); } final Pair<String, String> additionalStringToSearch = processor.getTextOccurrenceSearchStrings(searchForInComments, newName); if (additionalStringToSearch != null && additionalStringToSearch.first.length() > 0) { addTextOccurrence( searchForInComments, result, projectScope, additionalStringToSearch.first, additionalStringToSearch.second); } } return result.toArray(new UsageInfo[result.size()]); }