下面列出了怎么用com.intellij.psi.search.PsiElementProcessor的API类实例代码及写法,或者点击链接到github查看源代码。
private static boolean processSubComponent(PsiElementProcessor<HaxeNamedComponent> processor, HaxeComponent component) {
final String componentName = component.getName();
if (componentName == null) {
return true;
}
if (!processor.execute(component)) {
return false;
}
if (component instanceof HaxeClass) {
for (HaxeNamedComponent subComponent : getNamedComponents((HaxeClass)component)) {
if (!processor.execute(subComponent)) {
return false;
}
}
}
return true;
}
static void chooseAmbiguousTargetAndPerform(@NotNull final Project project, final Editor editor,
@NotNull PsiElementProcessor<PsiElement> processor) {
if (editor == null) {
Messages.showMessageDialog(project, FindBundle.message("find.no.usages.at.cursor.error"),
CommonBundle.getErrorTitle(), Messages.getErrorIcon());
} else {
int offset = editor.getCaretModel().getOffset();
boolean chosen = GotoDeclarationAction.chooseAmbiguousTarget(editor, offset, processor,
FindBundle.message("find.usages.ambiguous.title", "crap"), null);
if (!chosen) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (editor.isDisposed() || !editor.getComponent().isShowing()) return;
HintManager.getInstance()
.showErrorHint(editor, FindBundle.message("find.no.usages.at.cursor.error"));
}
}, project.getDisposed());
}
}
}
/**
* Recursive (depth first) search for first element of any of given {@code classes}.
*
* @param element a PSI element to start search from.
* @param strict if false the {@code element} is also included in the search.
* @param classes element types to search for.
* @param <T> type to cast found element to.
* @return first found element, or null if nothing found.
*/
@Nullable
@Contract("null, _, _ -> null")
public static <T extends PsiElement> T findChildOfAnyType(@Nullable final PsiElement element, final boolean strict, @Nonnull final Class<? extends T>... classes) {
PsiElementProcessor.FindElement<PsiElement> processor = new PsiElementProcessor.FindElement<PsiElement>() {
@Override
public boolean execute(@Nonnull PsiElement each) {
if (strict && each == element) return true;
if (instanceOf(each, classes)) {
return setFound(each);
}
return true;
}
};
processElements(element, processor);
//noinspection unchecked
return (T)processor.getFoundElement();
}
@Nonnull
public static <T extends PsiElement> Collection<T> findChildrenOfAnyType(@Nullable final PsiElement element, @Nonnull final Class<? extends T>... classes) {
if (element == null) {
return ContainerUtil.emptyList();
}
PsiElementProcessor.CollectElements<T> processor = new PsiElementProcessor.CollectElements<T>() {
@Override
public boolean execute(@Nonnull T each) {
if (each == element) return true;
if (instanceOf(each, classes)) {
return super.execute(each);
}
return true;
}
};
processElements(element, processor);
return processor.getCollection();
}
@Override
public boolean processChildren(PsiElementProcessor<PsiFileSystemItem> processor) {
checkValid();
ProgressIndicatorProvider.checkCanceled();
for (VirtualFile vFile : myFile.getChildren()) {
boolean isDir = vFile.isDirectory();
if (processor instanceof PsiFileSystemItemProcessor && !((PsiFileSystemItemProcessor)processor).acceptItem(vFile.getName(), isDir)) {
continue;
}
if (isDir) {
PsiDirectory dir = myManager.findDirectory(vFile);
if (dir != null) {
if (!processor.execute(dir)) return false;
}
}
else {
PsiFile file = myManager.findFile(vFile);
if (file != null) {
if (!processor.execute(file)) return false;
}
}
}
return true;
}
@Override
@Nonnull
public PsiElement[] getChildren() {
checkValid();
VirtualFile[] files = myFile.getChildren();
final ArrayList<PsiElement> children = new ArrayList<PsiElement>(files.length);
processChildren(new PsiElementProcessor<PsiFileSystemItem>() {
@Override
public boolean execute(@Nonnull final PsiFileSystemItem element) {
children.add(element);
return true;
}
});
return PsiUtilCore.toPsiElementArray(children);
}
static void chooseAmbiguousTargetAndPerform(@Nonnull final Project project, final Editor editor, @Nonnull PsiElementProcessor<PsiElement> processor) {
if (editor == null) {
Messages.showMessageDialog(project, FindBundle.message("find.no.usages.at.cursor.error"), CommonBundle.getErrorTitle(), Messages.getErrorIcon());
}
else {
int offset = editor.getCaretModel().getOffset();
boolean chosen = GotoDeclarationAction.chooseAmbiguousTarget(editor, offset, processor, FindBundle.message("find.usages.ambiguous.title"), null);
if (!chosen) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (editor.isDisposed() || !editor.getComponent().isShowing()) return;
HintManager.getInstance().showErrorHint(editor, FindBundle.message("find.no.usages.at.cursor.error"));
}
}, project.getDisposed());
}
}
}
static void chooseAmbiguousTargetAndPerform(@NotNull final Project project,
final Editor editor,
@NotNull PsiElementProcessor<PsiElement> processor) {
if (editor == null) {
Messages.showMessageDialog(project, FindBundle.message("find.no.usages.at.cursor.error"),
CommonBundle.getErrorTitle(), Messages.getErrorIcon());
}
else {
int offset = editor.getCaretModel().getOffset();
boolean chosen = GotoDeclarationAction.chooseAmbiguousTarget(editor, offset, processor,
FindBundle.message("find.usages.ambiguous.title", "crap"), null);
if (!chosen) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (editor.isDisposed() || !editor.getComponent().isShowing()) return;
HintManager.getInstance().showErrorHint(editor, FindBundle.message("find.no.usages.at.cursor.error"));
}
}, project.getDisposed());
}
}
}
@Override
protected void
buildLanguageFoldRegions(@NotNull final List<FoldingDescriptor> descriptors,
@NotNull PsiElement root,
@NotNull Document document,
boolean quick) {
if (!(root instanceof HaskellFile)) return;
HaskellFile file = (HaskellFile) root;
final Set<PsiElement> seenComments = ContainerUtil.newHashSet();
if (!quick) {
PsiTreeUtil.processElements(file, new PsiElementProcessor() {
@Override
public boolean execute(@NotNull PsiElement element) {
if (element.getNode().getElementType().equals(HaskellTypes.COMMENT)) {
addCommentFolds((PsiComment) element, seenComments, descriptors);
} else if (HaskellParserDefinition.COMMENTS.contains(element.getNode().getElementType())) {
TextRange range = element.getTextRange();
String placeholderText = getPlaceholderText(element.getNode());
// Only fold if we actually save space to prevent
// assertions from kicking in. Means {- -} will not fold.
if (placeholderText != null && range.getLength() > 1 &&
range.getLength() > placeholderText.length()) {
descriptors.add(new FoldingDescriptor(element, range));
}
}
return true;
}
});
}
}
public static List<PsiFile> findLayoutFilesInsideMethod(PsiMethod psiMethod) {
final List<PsiFile> xmlFiles = new ArrayList<PsiFile>();
PsiTreeUtil.processElements(psiMethod, new PsiElementProcessor() {
@Override
public boolean execute(@NotNull PsiElement element) {
if (element instanceof PsiMethodCallExpression) {
PsiMethod psiMethodResolved = ((PsiMethodCallExpression) element).resolveMethod();
if (psiMethodResolved != null) {
String methodName = psiMethodResolved.getName();
// @TODO: implement instance check
if ("setContentView".equals(methodName)) {
PsiExpression[] expressions = ((PsiMethodCallExpression) element).getArgumentList().getExpressions();
if (expressions.length > 0 && expressions[0] instanceof PsiReferenceExpression) {
PsiFile xmlFile = AndroidUtils.findXmlResource((PsiReferenceExpression) expressions[0]);
if (xmlFile != null) {
xmlFiles.add(xmlFile);
}
}
}
}
}
return true;
}
});
return xmlFiles;
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
if (candidates.size() > 1) {
NavigationUtil.getPsiElementPopup(
candidates.toArray(new PsiElement[candidates.size()]),
new DefaultPsiElementCellRenderer(),
HaxeBundle.message("choose.class.to.import.title"),
new PsiElementProcessor<PsiElement>() {
public boolean execute(@NotNull final PsiElement element) {
CommandProcessor.getInstance().executeCommand(
project,
new Runnable() {
public void run() {
doImport(editor, element);
}
},
getClass().getName(),
this
);
return false;
}
}
).showInBestPositionFor(editor);
}
else {
doImport(editor, candidates.iterator().next());
}
}
private static void processComponents(PsiFile psiFile, PsiElementProcessor<HaxeNamedComponent> processor) {
// top-level components
final List<HaxeClass> classes = HaxeResolveUtil.findComponentDeclarations(psiFile);
for (HaxeClass cls : classes) {
if (!processSubComponent(processor, cls)) {
return;
}
}
}
public static boolean processElements(@Nonnull PsiElementProcessor processor, @Nullable PsiElement... elements) {
if (elements == null || elements.length == 0) return true;
for (PsiElement element : elements) {
if (!processElements(element, processor)) return false;
}
return true;
}
protected static boolean processFileSystemItem(PsiElementProcessor<PsiFileSystemItem> processor, PsiFileSystemItem element) {
if (processor instanceof PsiFileSystemItemProcessor && !((PsiFileSystemItemProcessor)processor).acceptItem(element.getName(), true)) {
return true;
}
return processor.execute(element);
}
@Override
@Nonnull
public PsiElement[] getChildren() {
final PsiElementProcessor.CollectElements<PsiFileSystemItem> collector = new PsiElementProcessor.CollectElements<PsiFileSystemItem>();
processChildren(collector);
return collector.toArray(new PsiFileSystemItem[0]);
}
@Nonnull
public static JBPopup getPsiElementPopup(@Nonnull PsiElement[] elements, @Nonnull final PsiElementListCellRenderer<PsiElement> renderer, final String title) {
return getPsiElementPopup(elements, renderer, title, new PsiElementProcessor<PsiElement>() {
@Override
public boolean execute(@Nonnull final PsiElement element) {
Navigatable descriptor = EditSourceUtil.getDescriptor(element);
if (descriptor != null && descriptor.canNavigate()) {
descriptor.navigate(true);
}
return true;
}
});
}
@Nonnull
public static <T extends PsiElement> JBPopup getPsiElementPopup(@Nonnull T[] elements,
@Nonnull final PsiElementListCellRenderer<T> renderer,
final String title,
@Nonnull final PsiElementProcessor<T> processor) {
return getPsiElementPopup(elements, renderer, title, processor, null);
}
private static void chooseAmbiguousTarget(final Editor editor, int offset, PsiElement[] elements, @Nullable PsiElementListCellRenderer<PsiElement> render) {
PsiElementProcessor<PsiElement> navigateProcessor = new PsiElementProcessor<PsiElement>() {
@Override
public boolean execute(@Nonnull final PsiElement element) {
gotoTargetElement(element);
return true;
}
};
boolean found = chooseAmbiguousTarget(editor, offset, navigateProcessor, CodeInsightBundle.message("declaration.navigation.title"), elements, render);
if (!found) {
HintManager.getInstance().showErrorHint(editor, "Cannot find declaration to go to");
}
}
public static boolean chooseAmbiguousTarget(@Nonnull Editor editor,
int offset,
@Nonnull PsiElementProcessor<PsiElement> processor,
@Nonnull String titlePattern,
@Nullable PsiElement[] elements) {
return chooseAmbiguousTarget(editor, offset, processor, titlePattern, elements, null);
}
@Nonnull
static Collection<AbstractTreeNode> getDirectoryChildrenImpl(@Nonnull Project project, @Nullable PsiDirectory directory, @Nonnull ViewSettings settings, @Nonnull PsiFileSystemItemFilter filter) {
final List<AbstractTreeNode> result = new ArrayList<>();
PsiElementProcessor<PsiFileSystemItem> processor = new PsiElementProcessor<PsiFileSystemItem>() {
@Override
public boolean execute(@Nonnull PsiFileSystemItem element) {
if (!filter.shouldShow(element)) {
// skip
}
else if (element instanceof PsiDirectory) {
result.add(new PsiDirectoryNode(project, (PsiDirectory)element, settings, filter) {
@Override
public Collection<AbstractTreeNode> getChildrenImpl() {
//noinspection ConstantConditions
return getDirectoryChildrenImpl(getProject(), getValue(), getSettings(), getFilter());
}
});
}
else if (element instanceof PsiFile) {
result.add(new PsiFileNode(project, (PsiFile)element, settings) {
@Override
public Comparable<ExtensionSortKey> getTypeSortKey() {
PsiFile value = getValue();
Language language = value == null ? null : value.getLanguage();
LanguageFileType fileType = language == null ? null : language.getAssociatedFileType();
return fileType == null ? null : new ExtensionSortKey(fileType.getDefaultExtension());
}
});
}
return true;
}
};
return AbstractTreeUi.calculateYieldingToWriteAction(() -> {
if (directory == null || !directory.isValid()) return Collections.emptyList();
directory.processChildren(processor);
return result;
});
}
@Override
public boolean processChildren(PsiElementProcessor<PsiFileSystemItem> psiElementProcessor) {
return false;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile psiFile) throws IncorrectOperationException {
DocumentUtil.writeInRunUndoTransparentAction(new Runnable() {
@Override
public void run() {
List<AndroidView> androidViews = AndroidUtils.getIDsFromXML(xmlFile);
PsiStatement psiStatement = PsiTreeUtil.getParentOfType(psiElement, PsiStatement.class);
if(psiStatement == null) {
return;
}
// collection class field
// check if we need to set them
PsiClass psiClass = PsiTreeUtil.getParentOfType(psiStatement, PsiClass.class);
Set<String> fieldSet = new HashSet<String>();
for(PsiField field: psiClass.getFields()) {
fieldSet.add(field.getName());
}
// collect this.foo = "" and (this.)foo = ""
// collection already init variables
final Set<String> thisSet = new HashSet<String>();
PsiTreeUtil.processElements(psiStatement.getParent(), new PsiElementProcessor() {
@Override
public boolean execute(@NotNull PsiElement element) {
if(element instanceof PsiThisExpression) {
attachFieldName(element.getParent());
} else if(element instanceof PsiAssignmentExpression) {
attachFieldName(((PsiAssignmentExpression) element).getLExpression());
}
return true;
}
private void attachFieldName(PsiElement psiExpression) {
if(!(psiExpression instanceof PsiReferenceExpression)) {
return;
}
PsiElement psiField = ((PsiReferenceExpression) psiExpression).resolve();
if(psiField instanceof PsiField) {
thisSet.add(((PsiField) psiField).getName());
}
}
});
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiStatement.getProject());
for (AndroidView v: androidViews) {
if(!fieldSet.contains(v.getFieldName())) {
String sb = "private " + v.getName() + " " + v.getFieldName() + ";";
psiClass.add(elementFactory.createFieldFromText(sb, psiClass));
}
if(!thisSet.contains(v.getFieldName())) {
String sb1;
if(variableName != null) {
sb1 = String.format("this.%s = (%s) %s.findViewById(%s);", v.getFieldName(), v.getName(), variableName, v.getId());
} else {
sb1 = String.format("this.%s = (%s) findViewById(%s);", v.getFieldName(), v.getName(), v.getId());
}
PsiStatement statementFromText = elementFactory.createStatementFromText(sb1, null);
psiStatement.getParent().addAfter(statementFromText, psiStatement);
}
}
JavaCodeStyleManager.getInstance(psiStatement.getProject()).shortenClassReferences(psiStatement.getParent());
new ReformatAndOptimizeImportsProcessor(psiStatement.getProject(), psiStatement.getContainingFile(), true).run();
}
});
}
@Override
public boolean processChildren(final PsiElementProcessor<PsiFileSystemItem> processor) {
return true;
}
@Nonnull
public static PsiElement[] collectElements(@Nullable PsiElement element, @Nonnull PsiElementFilter filter) {
PsiElementProcessor.CollectFilteredElements<PsiElement> processor = new PsiElementProcessor.CollectFilteredElements<PsiElement>(filter);
processElements(element, processor);
return processor.toArray();
}
@Override
public boolean processChildren(PsiElementProcessor<PsiFileSystemItem> processor) {
throw createException();
}
@Override
public boolean processChildren(@Nonnull final PsiElementProcessor<PsiFileSystemItem> processor) {
return true;
}
@Override
public boolean processChildren(@Nonnull final PsiElementProcessor<PsiFileSystemItem> processor) {
return true;
}
@Nonnull
public static <T extends PsiElement> JBPopup getPsiElementPopup(@Nonnull T[] elements,
@Nonnull final PsiElementListCellRenderer<T> renderer,
@Nullable final String title,
@Nonnull final PsiElementProcessor<T> processor,
@Nullable final T selection) {
final JList list = new JBList(elements);
HintUpdateSupply.installSimpleHintUpdateSupply(list);
list.setCellRenderer(renderer);
list.setFont(EditorUtil.getEditorFont());
if (selection != null) {
list.setSelectedValue(selection, true);
}
final Runnable runnable = () -> {
int[] ids = list.getSelectedIndices();
if (ids == null || ids.length == 0) return;
for (Object element : list.getSelectedValues()) {
if (element != null) {
processor.execute((T)element);
}
}
};
PopupChooserBuilder builder = new PopupChooserBuilder(list);
if (title != null) {
builder.setTitle(title);
}
renderer.installSpeedSearch(builder, true);
JBPopup popup = builder.setItemChoosenCallback(runnable).createPopup();
builder.getScrollPane().setBorder(null);
builder.getScrollPane().setViewportBorder(null);
hidePopupIfDumbModeStarts(popup, elements[0].getProject());
return popup;
}
public FilterElementProcessor(ElementFilter filter, PsiElementProcessor processor, List container){
myFilter = filter;
myProcessor = processor;
myResults = container;
}
public FilterElementProcessor(ElementFilter filter, PsiElementProcessor proc){
this(filter, proc, new ArrayList());
}