@Nullable public static PsiQualifiedReference getClassReferenceToShorten( @NotNull final PsiClass refClass, final boolean addImports, @NotNull final PsiQualifiedReference reference) { PsiClass parentClass = refClass.getContainingClass(); if (parentClass != null) { JavaPsiFacade facade = JavaPsiFacade.getInstance(parentClass.getProject()); final PsiResolveHelper resolveHelper = facade.getResolveHelper(); if (resolveHelper.isAccessible(refClass, reference, null) && isSafeToShortenReference(reference.getReferenceName(), reference, refClass)) { return reference; } if (!CodeStyleSettingsManager.getSettings(reference.getProject()) .INSERT_INNER_CLASS_IMPORTS) { final PsiElement qualifier = reference.getQualifier(); if (qualifier instanceof PsiQualifiedReference) { return getClassReferenceToShorten( parentClass, addImports, (PsiQualifiedReference) qualifier); } return null; } } if (addImports && !((PsiImportHolder) reference.getContainingFile()).importClass(refClass)) return null; if (!isSafeToShortenReference(reference, refClass)) return null; return reference; }
@NotNull private static ASTNode replaceReferenceWithShort(PsiQualifiedReference reference) { final ASTNode node = reference.getNode(); assert node != null; dequalifyImpl((CompositeElement) node); return node; }
@Override public void actionPerformed(AnActionEvent e) { DataContext dataContext = e.getDataContext(); final Editor editor = CommonDataKeys.EDITOR.getData(dataContext); PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext); final Project project = file.getProject(); PsiDocumentManager.getInstance(project).commitAllDocuments(); final TextRange selection = new TextRange( editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd()); PsiElement current = file.findElementAt(selection.getStartOffset()); int startOffset = selection.getStartOffset(); while (current instanceof PsiWhiteSpace) { current = current.getNextSibling(); if (current == null) break; startOffset = current.getTextRange().getStartOffset(); } if (startOffset >= selection.getEndOffset()) startOffset = selection.getStartOffset(); final PsiElement[] psiElements = PsiTreeUtil.collectElements( file, new PsiElementFilter() { @Override public boolean isAccepted(PsiElement element) { return selection.contains(element.getTextRange()) && element.getReferences().length > 0; } }); final Document document = EditorFactory.getInstance() .createDocument( editor.getDocument().getText().substring(startOffset, selection.getEndOffset())); final boolean isXml = file.getLanguage().is(StdLanguages.XML); final int offsetDelta = startOffset; new WriteCommandAction.Simple(project, (String) null) { @Override protected void run() throws Throwable { Map<RangeMarker, String> rangeToText = new HashMap<RangeMarker, String>(); for (PsiElement element : psiElements) { for (PsiReference reference : element.getReferences()) { if (!(reference instanceof PsiQualifiedReference) || ((PsiQualifiedReference) reference).getQualifier() == null) { String canonicalText = reference.getCanonicalText(); LOG.assertTrue(canonicalText != null, reference.getClass()); TextRange referenceRange = reference.getRangeInElement(); final TextRange elementTextRange = element.getTextRange(); LOG.assertTrue(elementTextRange != null, elementTextRange); final TextRange range = elementTextRange.cutOut(referenceRange).shiftRight(-offsetDelta); final String oldText = document.getText(range); // workaround for Java references: canonicalText contains generics, and we need to cut // them off because otherwise // they will be duplicated int pos = canonicalText.indexOf('<'); if (pos > 0 && !oldText.contains("<")) { canonicalText = canonicalText.substring(0, pos); } if (isXml) { // strip namespace prefixes pos = canonicalText.lastIndexOf(':'); if (pos >= 0 && pos < canonicalText.length() - 1 && !oldText.contains(":")) { canonicalText = canonicalText.substring(pos + 1); } } if (!canonicalText.equals(oldText)) { rangeToText.put(document.createRangeMarker(range), canonicalText); } } } } for (Map.Entry<RangeMarker, String> entry : rangeToText.entrySet()) { document.replaceString( entry.getKey().getStartOffset(), entry.getKey().getEndOffset(), entry.getValue()); } } }.execute(); final TemplateImpl template = new TemplateImpl( TemplateListPanel.ABBREVIATION, document.getText(), TemplateSettings.USER_GROUP_NAME); template.setToReformat(true); PsiFile copy; AccessToken token = WriteAction.start(); try { copy = TemplateManagerImpl.insertDummyIdentifier(editor, file); } finally { token.finish(); } Set<TemplateContextType> applicable = TemplateManagerImpl.getApplicableContextTypes(copy, startOffset); for (TemplateContextType contextType : TemplateManagerImpl.getAllContextTypes()) { template.getTemplateContext().setEnabled(contextType, applicable.contains(contextType)); } final LiveTemplatesConfigurable configurable = new LiveTemplatesConfigurable(); ShowSettingsUtil.getInstance() .editConfigurable( project, configurable, () -> configurable.getTemplateListPanel().addTemplate(template)); }