@Override protected void collectAdditionalElementsToRename(List<Pair<PsiElement, TextRange>> stringUsages) { if (isReplaceAllOccurrences()) { for (E expression : getOccurrences()) { LOG.assertTrue(expression.isValid(), expression.getText()); stringUsages.add( Pair.<PsiElement, TextRange>create( expression, new TextRange(0, expression.getTextLength()))); } } else if (getExpr() != null) { correctExpression(); final E expr = getExpr(); LOG.assertTrue(expr.isValid(), expr.getText()); stringUsages.add( Pair.<PsiElement, TextRange>create(expr, new TextRange(0, expr.getTextLength()))); } final V localVariable = getLocalVariable(); if (localVariable != null) { final PsiElement nameIdentifier = localVariable.getNameIdentifier(); if (nameIdentifier != null) { int length = nameIdentifier.getTextLength(); stringUsages.add( Pair.<PsiElement, TextRange>create(nameIdentifier, new TextRange(0, length))); } } }
@Nullable private String verifyInnerClassDestination() { PsiClass targetClass = findTargetClass(); if (targetClass == null) return null; for (PsiElement element : myElementsToMove) { if (PsiTreeUtil.isAncestor(element, targetClass, false)) { return RefactoringBundle.message("move.class.to.inner.move.to.self.error"); } final Language targetClassLanguage = targetClass.getLanguage(); if (!element.getLanguage().equals(targetClassLanguage)) { return RefactoringBundle.message( "move.to.different.language", UsageViewUtil.getType(element), ((PsiClass) element).getQualifiedName(), targetClass.getQualifiedName()); } if (element.getLanguage().equals(Language.findLanguageByID("Groovy"))) { return RefactoringBundle.message("dont.support.inner.classes", "Groovy"); } } while (targetClass != null) { if (targetClass.getContainingClass() != null && !targetClass.hasModifierProperty(PsiModifier.STATIC)) { return RefactoringBundle.message("move.class.to.inner.nonstatic.error"); } targetClass = targetClass.getContainingClass(); } return null; }
@Override public final void actionPerformed(final AnActionEvent event) { final DataContext dataContext = event.getDataContext(); final HierarchyBrowserBaseEx browser = (HierarchyBrowserBaseEx) dataContext.getData(myBrowserDataKey); if (browser == null) return; final PsiElement selectedElement = browser.getSelectedElement(); if (selectedElement == null || !browser.isApplicableElement(selectedElement)) return; final String currentViewType = browser.myCurrentViewType; Disposer.dispose(browser); final HierarchyProvider provider = BrowseHierarchyActionBase.findProvider( myProviderLanguageExtension, selectedElement, selectedElement.getContainingFile(), event.getDataContext()); final HierarchyBrowser newBrowser = BrowseHierarchyActionBase.createAndAddToPanel( selectedElement.getProject(), provider, selectedElement); ApplicationManager.getApplication() .invokeLater( () -> ((HierarchyBrowserBaseEx) newBrowser) .changeView(correctViewType(browser, currentViewType))); }
private void updateEditorText() { disposeNonTextEditor(); final PsiElement elt = myElements[myIndex].getNavigationElement(); Project project = elt.getProject(); PsiFile psiFile = getContainingFile(elt); final VirtualFile vFile = psiFile.getVirtualFile(); if (vFile == null) return; final FileEditorProvider[] providers = FileEditorProviderManager.getInstance().getProviders(project, vFile); for (FileEditorProvider provider : providers) { if (provider instanceof TextEditorProvider) { updateTextElement(elt); myBinarySwitch.show(myViewingPanel, TEXT_PAGE_KEY); break; } else if (provider.accept(project, vFile)) { myCurrentNonTextEditorProvider = provider; myNonTextEditor = myCurrentNonTextEditorProvider.createEditor(project, vFile); myBinaryPanel.removeAll(); myBinaryPanel.add(myNonTextEditor.getComponent()); myBinarySwitch.show(myViewingPanel, BINARY_PAGE_KEY); break; } } }
public PsiDirectory[] getSelectedDirectories() { final PsiElement[] elements = getSelectedPSIElements(); if (elements.length == 1) { final PsiElement element = elements[0]; if (element instanceof PsiDirectory) { return new PsiDirectory[] {(PsiDirectory) element}; } else if (element instanceof PsiDirectoryContainer) { return ((PsiDirectoryContainer) element).getDirectories(); } else { final PsiFile containingFile = element.getContainingFile(); if (containingFile != null) { final PsiDirectory psiDirectory = containingFile.getContainingDirectory(); if (psiDirectory != null) { return new PsiDirectory[] {psiDirectory}; } final VirtualFile file = containingFile.getVirtualFile(); if (file instanceof VirtualFileWindow) { final VirtualFile delegate = ((VirtualFileWindow) file).getDelegate(); final PsiFile delegatePsiFile = containingFile.getManager().findFile(delegate); if (delegatePsiFile != null && delegatePsiFile.getContainingDirectory() != null) { return new PsiDirectory[] {delegatePsiFile.getContainingDirectory()}; } } return PsiDirectory.EMPTY_ARRAY; } } } else { final DefaultMutableTreeNode selectedNode = getSelectedNode(); if (selectedNode != null) { return getSelectedDirectoriesInAmbiguousCase(selectedNode); } } return PsiDirectory.EMPTY_ARRAY; }
protected void restoreState(@NotNull final V psiField) { if (!ReadonlyStatusHandler.ensureDocumentWritable( myProject, InjectedLanguageUtil.getTopLevelEditor(myEditor).getDocument())) return; ApplicationManager.getApplication() .runWriteAction( () -> { final PsiFile containingFile = psiField.getContainingFile(); final RangeMarker exprMarker = getExprMarker(); if (exprMarker != null) { myExpr = restoreExpression(containingFile, psiField, exprMarker, myExprText); } if (myLocalMarker != null) { final PsiElement refVariableElement = containingFile.findElementAt(myLocalMarker.getStartOffset()); if (refVariableElement != null) { final PsiElement parent = refVariableElement.getParent(); if (parent instanceof PsiNamedElement) { ((PsiNamedElement) parent).setName(myLocalName); } } final V localVariable = getLocalVariable(); if (localVariable != null && localVariable.isPhysical()) { myLocalVariable = localVariable; final PsiElement nameIdentifier = localVariable.getNameIdentifier(); if (nameIdentifier != null) { myLocalMarker = createMarker(nameIdentifier); } } } final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers(); for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) { RangeMarker marker = occurrenceMarkers.get(i); if (getExprMarker() != null && marker.getStartOffset() == getExprMarker().getStartOffset() && myExpr != null) { myOccurrences[i] = myExpr; continue; } final E psiExpression = restoreExpression( containingFile, psiField, marker, getLocalVariable() != null ? myLocalName : myExprText); if (psiExpression != null) { myOccurrences[i] = psiExpression; } } if (myExpr != null && myExpr.isPhysical()) { myExprMarker = createMarker(myExpr); } myOccurrenceMarkers = null; deleteTemplateField(psiField); }); }
public Info(@NotNull PsiElement elementAtPointer) { this( elementAtPointer, Collections.singletonList( new TextRange( elementAtPointer.getTextOffset(), elementAtPointer.getTextOffset() + elementAtPointer.getTextLength()))); }
final boolean isValidBase() { if (PsiDocumentManager.getInstance(myProject).getUncommittedDocuments().length > 0) { return myCachedIsValidBase; } final PsiElement element = mySmartPsiElementPointer.getElement(); myCachedIsValidBase = element != null && isApplicableElement(element) && element.isValid(); return myCachedIsValidBase; }
@Nullable protected PsiElement getPSIElement(@Nullable final Object element) { if (element instanceof PsiElement) { PsiElement psiElement = (PsiElement) element; if (psiElement.isValid()) { return psiElement; } } return null; }
private void getInjectedPsiFiles( @NotNull final List<PsiElement> elements1, @NotNull final List<PsiElement> elements2, @NotNull final ProgressIndicator progress, @NotNull final Set<PsiFile> outInjected) { List<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(myFile); Collection<PsiElement> hosts = new THashSet<PsiElement>(elements1.size() + elements2.size() + injected.size()); // rehighlight all injected PSI regardless the range, // since change in one place can lead to invalidation of injected PSI in (completely) other // place. for (DocumentWindow documentRange : injected) { progress.checkCanceled(); if (!documentRange.isValid()) continue; PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(documentRange); if (file == null) continue; PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file); if (context != null && context.isValid() && !file.getProject().isDisposed() && (myUpdateAll || new ProperTextRange(myStartOffset, myEndOffset) .intersects(context.getTextRange()))) { hosts.add(context); } } hosts.addAll(elements1); hosts.addAll(elements2); final PsiLanguageInjectionHost.InjectedPsiVisitor visitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit( @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) { synchronized (outInjected) { outInjected.add(injectedPsi); } } }; if (!JobUtil.invokeConcurrentlyUnderProgress( new ArrayList<PsiElement>(hosts), progress, false, new Processor<PsiElement>() { @Override public boolean process(PsiElement element) { progress.checkCanceled(); InjectedLanguageUtil.enumerate(element, myFile, false, visitor); return true; } })) throw new ProcessCanceledException(); }
public MoveClassesOrPackagesDialog( Project project, boolean searchTextOccurences, PsiElement[] elementsToMove, final PsiElement initialTargetElement, MoveCallback moveCallback) { super(project, true); myElementsToMove = elementsToMove; myMoveCallback = moveCallback; myManager = PsiManager.getInstance(myProject); setTitle(MoveHandler.REFACTORING_NAME); mySearchTextOccurencesEnabled = searchTextOccurences; selectInitialCard(); init(); if (initialTargetElement instanceof PsiClass) { myMakeInnerClassOfRadioButton.setSelected(true); myInnerClassChooser.setText(((PsiClass) initialTargetElement).getQualifiedName()); ApplicationManager.getApplication() .invokeLater( () -> myInnerClassChooser.requestFocus(), ModalityState.stateForComponent(myMainPanel)); } else if (initialTargetElement instanceof PsiPackage) { myClassPackageChooser.setText(((PsiPackage) initialTargetElement).getQualifiedName()); } updateControlsEnabled(); myToPackageRadioButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { updateControlsEnabled(); myClassPackageChooser.requestFocus(); } }); myMakeInnerClassOfRadioButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { updateControlsEnabled(); myInnerClassChooser.requestFocus(); } }); for (PsiElement element : elementsToMove) { if (element.getContainingFile() != null) { myOpenInEditorPanel.add(initOpenInEditorCb(), BorderLayout.EAST); break; } } }
private void doWriteAction(final ImportCandidateHolder item) { PsiElement src = item.getImportable(); new WriteCommandAction( src.getProject(), PyBundle.message("ACT.CMD.use.import"), myTarget.getContainingFile()) { @Override protected void run(@NotNull Result result) throws Throwable { doIt(item); } }.execute(); if (myOnDoneCallback != null) { myOnDoneCallback.run(); } }
@Override public void actionPerformed(AnActionEvent e) { PsiElement element = myElements[myIndex]; PsiElement navigationElement = element.getNavigationElement(); PsiFile file = getContainingFile(navigationElement); if (file == null) return; VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile == null) return; Project project = element.getProject(); FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFile, navigationElement.getTextOffset()); fileEditorManager.openTextEditor(descriptor, myFocusEditor); }
private void doGenerate( final Editor editor, final PsiFile file, final PsiClass targetClass, final TestFramework framework) { if (framework instanceof JavaTestFramework && ((JavaTestFramework) framework).isSingleConfig()) { PsiElement alreadyExist = null; switch (myMethodKind) { case SET_UP: alreadyExist = framework.findSetUpMethod(targetClass); break; case TEAR_DOWN: alreadyExist = framework.findTearDownMethod(targetClass); break; default: break; } if (alreadyExist instanceof PsiMethod) { editor.getCaretModel().moveToOffset(alreadyExist.getNavigationElement().getTextOffset()); HintManager.getInstance() .showErrorHint( editor, "Method " + ((PsiMethod) alreadyExist).getName() + " already exists"); return; } } if (!CommonRefactoringUtil.checkReadOnlyStatus(file)) return; WriteCommandAction.runWriteCommandAction( file.getProject(), new Runnable() { @Override public void run() { try { PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments(); PsiMethod method = generateDummyMethod(editor, file); if (method == null) return; TestIntegrationUtils.runTestMethodTemplate( myMethodKind, framework, editor, targetClass, method, "name", false, null); } catch (IncorrectOperationException e) { HintManager.getInstance() .showErrorHint(editor, "Cannot generate method: " + e.getMessage()); LOG.warn(e); } } }); }
private void addToExistingImport(PyImportElement src) { final PyElementGenerator gen = PyElementGenerator.getInstance(myTarget.getProject()); // did user choose 'import' or 'from import'? PsiElement parent = src.getParent(); if (parent instanceof PyFromImportStatement) { // add another import element right after the one we got PsiElement newImportElement = gen.createImportElement(LanguageLevel.getDefault(), myName); parent.add(newImportElement); } else { // just 'import' // all we need is to qualify our target myTarget.replace( gen.createExpressionFromText( LanguageLevel.forElement(myTarget), src.getVisibleName() + "." + myName)); } }
public boolean isValid(Document document) { if (!myTargetElement.isValid()) return false; if (myTargetElement == myElementAtPointer || myTargetElement == myElementAtPointer.getParent()) return false; return rangesAreCorrect(document); }
public void deleteElement(DataContext dataContext) { List<PsiElement> allElements = Arrays.asList(getElementsToDelete()); List<PsiElement> validElements = new ArrayList<PsiElement>(); for (PsiElement psiElement : allElements) { if (psiElement != null && psiElement.isValid()) validElements.add(psiElement); } final PsiElement[] elements = validElements.toArray(new PsiElement[validElements.size()]); LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting")); try { DeleteHandler.deletePsiElement(elements, myProject); } finally { a.finish(); } }
protected void updateTitle(@Nullable V variable, String value) { if (variable == null) return; final String variableText = variable.getText(); final PsiElement identifier = variable.getNameIdentifier(); if (identifier != null) { final int startOffsetInParent = identifier.getStartOffsetInParent(); setPreviewText( variableText.substring(0, startOffsetInParent) + value + variableText.substring(startOffsetInParent + identifier.getTextLength())); } else { setPreviewText(variableText.replaceFirst(variable.getName(), value)); } revalidate(); }
private void invokeMoveToPackage() { final MoveDestination destination = selectDestination(); if (destination == null) return; saveRefactoringSettings(); for (final PsiElement element : myElementsToMove) { String message = verifyDestinationForElement(element, destination); if (message != null) { String helpId = HelpID.getMoveHelpID(myElementsToMove[0]); CommonRefactoringUtil.showErrorMessage( RefactoringBundle.message("error.title"), message, helpId, getProject()); return; } } try { for (PsiElement element : myElementsToMove) { if (element instanceof PsiClass) { final PsiClass aClass = (PsiClass) element; LOG.assertTrue(aClass.isPhysical(), aClass); /*PsiElement toAdd; if (aClass.getContainingFile() instanceof PsiJavaFile && ((PsiJavaFile)aClass.getContainingFile()).getClasses().length > 1) { toAdd = aClass; } else { toAdd = aClass.getContainingFile(); }*/ final PsiDirectory targetDirectory = destination.getTargetIfExists(element.getContainingFile()); if (targetDirectory != null) { MoveFilesOrDirectoriesUtil.checkMove(aClass, targetDirectory); } } } MoveClassesOrPackagesProcessor processor = createMoveToPackageProcessor(destination, myElementsToMove, myMoveCallback); if (processor.verifyValidPackageName()) { processor.setOpenInEditor(isOpenInEditor()); invokeRefactoring(processor); } } catch (IncorrectOperationException e) { String helpId = HelpID.getMoveHelpID(myElementsToMove[0]); CommonRefactoringUtil.showErrorMessage( RefactoringBundle.message("error.title"), e.getMessage(), helpId, getProject()); } }
public static PsiExpression[] findVariableOccurrences( final PsiElement[] scopeElements, final PsiVariable variable) { final ArrayList<PsiExpression> result = new ArrayList<PsiExpression>(); for (final PsiElement element : scopeElements) { element.accept( new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceExpression(final PsiReferenceExpression expression) { super.visitReferenceExpression(expression); if (!expression.isQualified() && expression.isReferenceTo(variable)) { result.add(expression); } } }); } return result.toArray(new PsiExpression[result.size()]); }
@Nullable private ExpressionEvaluator getExpressionEvaluator(DebuggerContextImpl debuggerContext) throws EvaluateException { if (myCurrentExpression instanceof PsiExpression) { return EvaluatorBuilderImpl.getInstance() .build(myCurrentExpression, debuggerContext.getSourcePosition()); } CodeFragmentFactory factory = DebuggerUtilsEx.getEffectiveCodeFragmentFactory(myCurrentExpression); TextWithImportsImpl textWithImports = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myCurrentExpression.getText()); if (factory == null) return null; JavaCodeFragment codeFragment = factory.createCodeFragment(textWithImports, myCurrentExpression.getContext(), getProject()); codeFragment.forceResolveScope(GlobalSearchScope.allScope(getProject())); return factory.getEvaluatorBuilder().build(codeFragment, debuggerContext.getSourcePosition()); }
@Nullable public String getInfo() { try { return generateInfo(myTargetElement, myElementAtPointer); } catch (IndexNotReadyException e) { showDumbModeNotification(myTargetElement.getProject()); return null; } }
@Nullable private static Pair<PsiElement, TextRange> findExpression( PsiElement element, boolean allowMethodCalls) { final EditorTextProvider textProvider = EditorTextProvider.EP.forLanguage(element.getLanguage()); if (textProvider != null) { return textProvider.findExpression(element, allowMethodCalls); } return null; }
private void addImportStatement(ImportCandidateHolder item) { final Project project = myTarget.getProject(); final PyElementGenerator gen = PyElementGenerator.getInstance(project); AddImportHelper.ImportPriority priority = AddImportHelper.getImportPriority(myTarget, item.getFile()); PsiFile file = myTarget.getContainingFile(); InjectedLanguageManager manager = InjectedLanguageManager.getInstance(project); if (manager.isInjectedFragment(file)) { file = manager.getTopLevelFile(myTarget); } // We are trying to import top-level module or package which thus cannot be qualified if (isRoot(item.getFile())) { if (myImportLocally) { AddImportHelper.addLocalImportStatement(myTarget, myName); } else { AddImportHelper.addImportStatement(file, myName, item.getAsName(), priority, null); } } else { final QualifiedName path = item.getPath(); final String qualifiedName = path != null ? path.toString() : ""; if (myUseQualifiedImport) { String nameToImport = qualifiedName; if (item.getImportable() instanceof PsiFileSystemItem) { nameToImport += "." + myName; } if (myImportLocally) { AddImportHelper.addLocalImportStatement(myTarget, nameToImport); } else { AddImportHelper.addImportStatement(file, nameToImport, item.getAsName(), priority, null); } myTarget.replace( gen.createExpressionFromText( LanguageLevel.forElement(myTarget), qualifiedName + "." + myName)); } else { if (myImportLocally) { AddImportHelper.addLocalFromImportStatement(myTarget, qualifiedName, myName); } else { AddImportHelper.addFromImportStatement( file, qualifiedName, myName, item.getAsName(), priority, null); } } } }
public static String getNewText(PsiElement elt) { Project project = elt.getProject(); PsiFile psiFile = getContainingFile(elt); final Document doc = PsiDocumentManager.getInstance(project).getDocument(psiFile); if (doc == null) return null; final ImplementationTextSelectioner implementationTextSelectioner = LanguageImplementationTextSelectioner.INSTANCE.forLanguage(elt.getLanguage()); int start = implementationTextSelectioner.getTextStartOffset(elt); final int end = implementationTextSelectioner.getTextEndOffset(elt); final int lineStart = doc.getLineStartOffset(doc.getLineNumber(start)); final int lineEnd = end < doc.getTextLength() ? doc.getLineEndOffset(doc.getLineNumber(end)) : doc.getTextLength(); return doc.getCharsSequence().subSequence(lineStart, lineEnd).toString(); }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ColorIconRenderer renderer = (ColorIconRenderer) o; if (myElement != null ? !myElement.equals(renderer.myElement) : renderer.myElement != null) return false; return true; }
/** * Alters either target (by qualifying a name) or source (by explicitly importing the name). * * @return true if action succeeded */ public boolean execute() { // check if the tree is sane PsiDocumentManager.getInstance(myTarget.getProject()).commitAllDocuments(); if (!myTarget.isValid()) return false; if ((myTarget instanceof PyQualifiedExpression) && ((((PyQualifiedExpression) myTarget).isQualified()))) return false; // we cannot be qualified for (ImportCandidateHolder item : mySources) { if (!item.getImportable().isValid()) return false; if (!item.getFile().isValid()) return false; if (item.getImportElement() != null && !item.getImportElement().isValid()) return false; } if (mySources.isEmpty()) { return false; } // act if (mySources.size() > 1) { selectSourceAndDo(); } else doWriteAction(mySources.get(0)); return true; }
private static void update( @NotNull PsiElement[] elements, @NotNull PairFunction<PsiElement[], List<FileDescriptor>, Boolean> fun) { List<PsiElement> candidates = new ArrayList<PsiElement>(elements.length); List<FileDescriptor> files = new ArrayList<FileDescriptor>(elements.length); final Set<String> names = new HashSet<String>(); for (PsiElement element : elements) { if (element instanceof PsiNamedElement) { names.add(((PsiNamedElement) element).getName()); } } for (PsiElement element : elements) { PsiFile file = getContainingFile(element); if (file == null) continue; final PsiElement parent = element.getParent(); files.add(new FileDescriptor(file, names.size() > 1 || parent == file ? element : parent)); candidates.add(element); } fun.fun(PsiUtilCore.toPsiElementArray(candidates), files); }
@Nullable private static String verifyDestinationForElement( final PsiElement element, final MoveDestination moveDestination) { final String message; if (element instanceof PsiDirectory) { message = moveDestination.verify((PsiDirectory) element); } else if (element instanceof PsiPackage) { message = moveDestination.verify((PsiPackage) element); } else { message = moveDestination.verify(element.getContainingFile()); } return message; }
@Override @NotNull public DocInfo getInfo() { AccessToken token = ReadAction.start(); try { return generateInfo(myTargetElement, myElementAtPointer); } catch (IndexNotReadyException e) { showDumbModeNotification(myTargetElement.getProject()); return DocInfo.EMPTY; } finally { token.finish(); } }