@NotNull public XPathType getExpectedType(XPathExpression expr) { final XmlTag tag = PsiTreeUtil.getContextOfType(expr, XmlTag.class, true); if (tag != null && XsltSupport.isXsltTag(tag)) { final XsltElement element = XsltElementFactory.getInstance().wrapElement(tag, XsltElement.class); if (element instanceof XsltVariable) { return ((XsltVariable) element).getType(); } else { final XmlAttribute attr = PsiTreeUtil.getContextOfType(expr, XmlAttribute.class, true); if (attr != null) { if (element instanceof XsltWithParam) { final XmlAttribute nameAttr = tag.getAttribute("name", null); if (nameAttr != null) { final XmlAttributeValue valueElement = nameAttr.getValueElement(); if (valueElement != null) { final PsiReference[] references = valueElement.getReferences(); for (PsiReference reference : references) { final PsiElement psiElement = reference.resolve(); if (psiElement instanceof XsltVariable) { return ((XsltVariable) psiElement).getType(); } } } } } else { final String name = attr.getName(); return getTypeForTag(tag, name); } } } } return XPathType.UNKNOWN; }
@Nullable public static PsiFile resolveFile(XmlAttribute location, PsiFile baseFile) { if (location == null) return null; final XmlAttributeValue valueElement = location.getValueElement(); if (valueElement == null) return null; // prefer direct relative path final String value = valueElement.getValue(); final PsiFile file = resolveFile(value, baseFile); if (file != baseFile && file instanceof XmlFile) { return file; } final PsiReference[] references = valueElement.getReferences(); for (PsiReference reference : references) { final PsiElement target = reference.resolve(); if (target == null && reference instanceof PsiPolyVariantReference) { final ResolveResult[] results = ((PsiPolyVariantReference) reference).multiResolve(false); for (ResolveResult result : results) { if (result.isValidResult()) { // TODO: how to weigh/prioritize the results? final PsiElement element = result.getElement(); if (element != baseFile && element instanceof XmlFile) { return (PsiFile) target; } } } } else if (target != baseFile && target instanceof XmlFile) { return (PsiFile) target; } } return null; }
@Nullable static PsiElement resolveReference(final PsiReference psiReference) { if (psiReference instanceof PsiPolyVariantReference) { final ResolveResult[] results = ((PsiPolyVariantReference) psiReference).multiResolve(true); if (results.length == 1) return results[0].getElement(); } return psiReference.resolve(); }
private void resolveReference( @NotNull PsiReference reference, @NotNull Set<PsiElement> resolved) { PsiElement element = reference.resolve(); if (element != null) { resolved.add(element); } refCount.incrementAndGet(); }
private static void rename( PsiReference ref, String newName, PsiManager manager, PsiMember elementToResolve) { final PsiElement renamed = ref.handleElementRename(newName); PsiElement newly_resolved = ref.resolve(); if (!manager.areElementsEquivalent(newly_resolved, elementToResolve)) { if (newly_resolved instanceof PsiMethod) { newly_resolved = GroovyPropertyUtils.findFieldForAccessor((PsiMethod) newly_resolved, false); } if (!manager.areElementsEquivalent(newly_resolved, elementToResolve)) { qualify(elementToResolve, renamed, newName); } } }
protected int getCaretOffset() { RangeMarker r; if (myLocalMarker != null) { final PsiReference reference = myExpr != null ? myExpr.getReference() : null; if (reference != null && reference.resolve() == myLocalVariable) { r = myExprMarker; } else { r = myLocalMarker; } } else { r = myExprMarker; } return r != null ? r.getStartOffset() : 0; }
@Nullable private static String getStringValue(@Nullable PsiElement psiElement, int depth) { if (psiElement == null || ++depth > 5) { return null; } if (psiElement instanceof StringLiteralExpression) { String resolvedString = ((StringLiteralExpression) psiElement).getContents(); if (StringUtils.isEmpty(resolvedString)) { return null; } return resolvedString; } if (psiElement instanceof Field) { return getStringValue(((Field) psiElement).getDefaultValue(), depth); } if (psiElement instanceof PhpReference) { PsiReference psiReference = psiElement.getReference(); if (psiReference == null) { return null; } PsiElement ref = psiReference.resolve(); if (ref instanceof PhpReference) { return getStringValue(psiElement, depth); } if (ref instanceof Field) { PsiElement resolved = ((Field) ref).getDefaultValue(); if (resolved instanceof StringLiteralExpression) { return ((StringLiteralExpression) resolved).getContents(); } } } return null; }
@Override public void renameElement( final PsiElement psiElement, final String newName, final UsageInfo[] usages, final RefactoringElementListener listener) throws IncorrectOperationException { final GrField field = (GrField) psiElement; final PsiMethod getter = GroovyPropertyUtils.findGetterForField(field); final PsiMethod setter = GroovyPropertyUtils.findSetterForField(field); final String newGetterName = (getter != null && getter.getName().startsWith("is") ? "is" : "get") + StringUtil.capitalize(newName); final String newSetterName = "set" + StringUtil.capitalize(newName); final PsiManager manager = field.getManager(); List<PsiReference> getterRefs = new ArrayList<PsiReference>(); List<PsiReference> setterRefs = new ArrayList<PsiReference>(); List<PsiReference> fieldRefs = new ArrayList<PsiReference>(); for (UsageInfo usage : usages) { final PsiElement element = usage.getElement(); if (element == null) continue; PsiReference ref = element.findReferenceAt(usage.startOffset); if (ref == null) continue; PsiElement resolved = ref.resolve(); if (manager.areElementsEquivalent(resolved, getter)) { if (isPropertyAccess(element)) { fieldRefs.add(ref); } else { getterRefs.add(ref); } } else if (manager.areElementsEquivalent(resolved, setter)) { if (isPropertyAccess(element)) { fieldRefs.add(ref); } else { setterRefs.add(ref); } } else if (manager.areElementsEquivalent(resolved, field)) { fieldRefs.add(ref); } else { ref.handleElementRename(newName); } } field.setName(newName); final PsiMethod newGetter = GroovyPropertyUtils.findGetterForField(field); doRename(newGetterName, manager, getterRefs, newGetter); final PsiMethod newSetter = GroovyPropertyUtils.findSetterForField(field); doRename(newSetterName, manager, setterRefs, newSetter); doRename(newName, manager, fieldRefs, field); listener.elementRenamed(field); }
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()]))); }
@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()]); }
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; }
@Nullable public PsiElement getContext() { final PsiReference contextRef = getContextReference(); return contextRef != null ? contextRef.resolve() : null; }