下面列出了com.intellij.psi.util.PsiTreeUtil#findCommonParent ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static Template buildTemplate(@NotNull XmlAttribute attr, List<XmlTag> refs) {
//XmlFile containingFile = (XmlFile)attr.getContainingFile();
PsiElement commonParent = PsiTreeUtil.findCommonParent(refs);
TemplateBuilderImpl builder = new TemplateBuilderImpl(attr);
XmlAttributeValue attrValue = attr.getValueElement();
PsiElement valuePsi = attrValue.getFirstChild().getNextSibling();
String flowNameValue = new String(attrValue.getValue());
builder.replaceElement(valuePsi,"PrimaryVariable", new TextExpression(flowNameValue), true);
/*
for (XmlTag ref : refs) {
if (ref.getContainingFile().equals(attr.getContainingFile())) {
XmlAttribute nextAttr = ref.getAttribute(MuleConfigConstants.NAME_ATTRIBUTE);
XmlAttributeValue nextValue = nextAttr.getValueElement();
PsiElement nextValuePsi = nextValue.getFirstChild().getNextSibling();
builder.replaceElement(nextValuePsi, "OtherVariable", "PrimaryVariable",false);
}
}
*/
return builder.buildInlineTemplate();
}
public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) {
PsiFile templateLanguageFile = PsiUtilCore.getTemplateLanguageFile(element.getContainingFile());
if (templateLanguageFile == null) {
return true;
}
Language language = templateLanguageFile.getLanguage();
if (language != LatteLanguage.INSTANCE) {
return true;
}
if (element.getParent() instanceof XmlElement || element.getParent() instanceof CssElement) {
return false;
}
if (element.getParent().getLanguage() == LatteLanguage.INSTANCE) {
return true;
}
PsiElement nextSibling;
for (nextSibling = PsiTreeUtil.nextLeaf(element); nextSibling instanceof PsiWhiteSpace; nextSibling = nextSibling.getNextSibling());
PsiElement psiElement = nextSibling == null ? null : PsiTreeUtil.findCommonParent(nextSibling, element);
boolean nextIsOuterLanguageElement = nextSibling instanceof OuterLanguageElement || nextSibling instanceof LatteMacroClassic;
return !nextIsOuterLanguageElement || psiElement == null || psiElement instanceof PsiFile;
}
@Nullable
public static DotNetExpression getSelectedExpression(@Nonnull final Project project,
@Nonnull PsiFile file,
@Nonnull final PsiElement element1,
@Nonnull final PsiElement element2)
{
PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2);
if(parent == null)
{
return null;
}
if(parent instanceof DotNetExpression)
{
return (DotNetExpression) parent;
}
return PsiTreeUtil.getParentOfType(parent, DotNetExpression.class);
}
private static <T extends XQueryPsiElement, U extends XQueryPsiElement>boolean processChildrenIfPlaceIsNotPartOfSameBinding(T module,
@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent,
@NotNull PsiElement place, Class<T> bindingClass, Class<U>... childClassesToSkip) {
PsiElement commonParent = PsiTreeUtil.findCommonParent(place, module);
T parentBinding = PsiTreeUtil.getParentOfType(place, bindingClass, true);
XQueryExprSingle expressionInModule = PsiTreeUtil.getChildOfType(module, XQueryExprSingle.class);
boolean inSameBinding = commonParent != null && commonParent.equals(module) && parentBinding != null && parentBinding.equals(module);
Collection<T> childBindings = PsiTreeUtil.findChildrenOfType(expressionInModule, bindingClass);
boolean partOfExpressionInBinding = childBindings.contains(parentBinding);
if (inSameBinding || partOfExpressionInBinding) {
return processor.execute(module, state);
} else {
if (!processor.execute(module, state)) {
return false;
} else {
return ResolveUtil.processChildren(module, processor, state, lastParent, place, childClassesToSkip);
}
}
}
@Nullable
public static PsiElement findCommonParent(final PsiElement root, final int startOffset, final int endOffset) {
if (startOffset == endOffset) return null;
final PsiElement left = findElementAtInRoot(root, startOffset);
PsiElement right = findElementAtInRoot(root, endOffset - 1);
if (left == null || right == null) return null;
PsiElement commonParent = PsiTreeUtil.findCommonParent(left, right);
if (commonParent == null) {
LOG.error("No common parent for "+left+" and "+right+"; root: "+root+"; startOffset: "+startOffset+"; endOffset: "+endOffset);
}
LOG.assertTrue(commonParent.getTextRange() != null, commonParent);
PsiElement parent = commonParent.getParent();
while (parent != null && commonParent.getTextRange().equals(parent.getTextRange())) {
commonParent = parent;
parent = parent.getParent();
}
return commonParent;
}
@Nullable
@RequiredUIAccess
private static PsiElement[] getElementList(@Nonnull PsiFile file, int rangeStart, int rangeEnd) {
PsiElement startElement = file.findElementAt(rangeStart);
if (startElement == null) return null;
PsiElement endElement = rangeEnd > rangeStart ? file.findElementAt(rangeEnd - 1) : startElement;
if (endElement == null) return null;
PsiElement element = PsiTreeUtil.findCommonParent(startElement, endElement);
while (element != null) {
List<MoveElementLeftRightHandler> handlers = MoveElementLeftRightHandler.EXTENSION.allForLanguage(element.getLanguage());
for (MoveElementLeftRightHandler handler : handlers) {
PsiElement[] elementList = handler.getMovableSubElements(element);
if (elementList.length > 1) {
Arrays.sort(elementList, BY_OFFSET);
PsiElement first = elementList[0];
PsiElement last = elementList[elementList.length - 1];
if (rangeStart >= first.getTextRange().getStartOffset() && rangeEnd <= last.getTextRange().getEndOffset() &&
(rangeStart >= first.getTextRange().getEndOffset() || rangeEnd <= last.getTextRange().getStartOffset())) {
return elementList;
}
}
}
element = element.getParent();
}
return null;
}
@Nullable
static ASTNode findContainingNode(@Nonnull PsiFile file, @Nullable TextRange range) {
Language language = file.getLanguage();
if (range == null) return null;
final FileViewProvider viewProvider = file.getViewProvider();
final PsiElement startElement = viewProvider.findElementAt(range.getStartOffset(), language);
final PsiElement endElement = viewProvider.findElementAt(range.getEndOffset() - 1, language);
final PsiElement commonParent = startElement != null && endElement != null ? PsiTreeUtil.findCommonParent(startElement, endElement) : null;
ASTNode node = null;
if (commonParent != null) {
node = commonParent.getNode();
// Find the topmost parent with the same range.
ASTNode parent = node.getTreeParent();
while (parent != null && parent.getTextRange().equals(commonParent.getTextRange())) {
node = parent;
parent = parent.getTreeParent();
}
}
if (node == null) {
node = file.getNode();
}
return node;
}
@Nullable
public UsageInfo getUsageInfo() {
if (myElementAnchors.length == 1) {
final PsiElement element = myElementAnchors[0].retrieve();
if (element == null || !element.isValid()) return null;
return new UsageInfo(element);
}
PsiElement parent = PsiTreeUtil.findCommonParent(getElements());
if (parent == null) return null;
int offs = parent.getTextRange().getStartOffset();
final int startOffsetInParent = getStartOffset() - offs;
final int endOffsetInParent = getEndOffset() - offs;
if (startOffsetInParent < 0) return null;
if (endOffsetInParent < startOffsetInParent) return null;
return new UsageInfo(parent, startOffsetInParent, endOffsetInParent);
}
@NotNull
public PsiElement[] getElementsToSurround(PsiFile psiFile, int i, int i1) {
PsiElement psiElement = psiFile.findElementAt(i);
PsiElement psiElement2 = psiFile.findElementAt(i1 - 1);
PsiElement commonParent = PsiTreeUtil.findCommonParent(psiElement, psiElement2);
PsiElement firstStatementStart = findStamentNodeFromParent(psiElement, commonParent);
PsiElement lastStatementStart = findStamentNodeFromParent(psiElement2, commonParent);
if (firstStatementStart != null && lastStatementStart != null) {
List<PsiElement> result = new ArrayList<PsiElement>();
for(PsiElement e = firstStatementStart; e != null ; e = e.getNextSibling()) {
result.add(e);
if (e == lastStatementStart) break;
}
if (result.get(result.size() - 1) == lastStatementStart) {
return result.toArray(new PsiElement[result.size()]);
}
}
System.out.println(firstStatementStart);
return new PsiElement[] {commonParent};
}
@Override
public void update(AnActionEvent anActionEvent)
{
//final VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(anActionEvent.getDataContext());
final PsiFile psiFile = anActionEvent.getData(CommonDataKeys.PSI_FILE);
final Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);
boolean inMuleFlow = false;
if (psiFile != null)
{
PsiElement muleFlowTagElement = null;
XmlTag muleFlowTag = null;
if (editor != null && editor.getSelectionModel() != null && editor.getSelectionModel().hasSelection()) {
PsiElement startPsi = psiFile.findElementAt(editor.getSelectionModel().getSelectionStart());
PsiElement endPsi = psiFile.findElementAt(editor.getSelectionModel().getSelectionEnd());
muleFlowTagElement = PsiTreeUtil.findCommonParent(startPsi, endPsi);
} else {//Just find element under the caret
muleFlowTagElement = anActionEvent.getData(LangDataKeys.PSI_ELEMENT);
}
if (muleFlowTagElement != null && muleFlowTagElement instanceof XmlTag) {
muleFlowTag = (XmlTag)muleFlowTagElement;
} else {
muleFlowTag = PsiTreeUtil.getParentOfType(muleFlowTagElement, XmlTag.class);
}
inMuleFlow = MuleConfigUtils.isInTopLevelTag(muleFlowTag);
}
anActionEvent.getPresentation().setEnabled(inMuleFlow);
anActionEvent.getPresentation().setVisible(inMuleFlow);
}
@RequiredReadAction
private static LineRange expandLineRangeToCoverPsiElements(final LineRange range, Editor editor, final PsiFile file)
{
Pair<PsiElement, PsiElement> psiRange = getElementRange(editor, file, range);
if(psiRange == null)
{
return null;
}
final PsiElement parent = PsiTreeUtil.findCommonParent(psiRange.getFirst(), psiRange.getSecond());
Pair<PsiElement, PsiElement> elementRange = getElementRange(parent, psiRange.getFirst(), psiRange.getSecond());
if(elementRange == null)
{
return null;
}
int endOffset = elementRange.getSecond().getTextRange().getEndOffset();
Document document = editor.getDocument();
if(endOffset > document.getTextLength())
{
LOG.assertTrue(!PsiDocumentManager.getInstance(file.getProject()).isUncommited(document));
LOG.assertTrue(PsiDocumentManagerImpl.checkConsistency(file, document));
}
int endLine;
if(endOffset == document.getTextLength())
{
endLine = document.getLineCount();
}
else
{
endLine = editor.offsetToLogicalPosition(endOffset).line + 1;
endLine = Math.min(endLine, document.getLineCount());
}
int startLine = Math.min(range.startLine, editor.offsetToLogicalPosition(elementRange.getFirst().getTextOffset()).line);
endLine = Math.max(endLine, range.endLine);
return new LineRange(startLine, endLine);
}
@Nullable
public static HaxeExpression getSelectedExpression(@NotNull final Project project,
@NotNull PsiFile file,
@NotNull final PsiElement element1,
@NotNull final PsiElement element2) {
PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2);
if (parent == null) {
return null;
}
if (parent instanceof HaxeExpression) {
return (HaxeExpression)parent;
}
return PsiTreeUtil.getParentOfType(parent, HaxeExpression.class);
}
public static <T extends XQueryPsiElement> boolean processChildren(PsiElement element, PsiScopeProcessor processor,
ResolveState substitutor, PsiElement lastParent, PsiElement place, Class<T>... childClassesToSkip) {
PsiElement run = lastParent == null ? element.getLastChild() : lastParent.getPrevSibling();
while (run != null) {
if (!isAnyOf(run, childClassesToSkip) &&PsiTreeUtil.findCommonParent(place, run) != run && !run.processDeclarations(processor, substitutor,
null, place)) {
return false;
}
run = run.getPrevSibling();
}
return true;
}
@RequiredReadAction
@Override
public PsiElement getPsiElement() {
PsiElement startElement = getStartElement();
if (myEndSmartPointer == null) {
return startElement;
}
PsiElement endElement = getEndElement();
if (startElement == endElement) {
return startElement;
}
if (startElement == null || endElement == null) return null;
return PsiTreeUtil.findCommonParent(startElement, endElement);
}
private static PsiElement scopeElementsUnion(PsiElement element1, PsiElement element2) {
if (PsiTreeUtil.isAncestor(element1, element2, false)) return element1;
if (PsiTreeUtil.isAncestor(element2, element1, false)) return element2;
PsiElement commonParent = PsiTreeUtil.findCommonParent(element1, element2);
if (commonParent == null) return null;
return commonParent;
}
@RequiredReadAction
private static <T extends PsiElement> T findElementInRange(@Nonnull PsiFile file,
int startOffset,
int endOffset,
@Nonnull Class<T> klass,
@Nonnull Language language,
@Nullable PsiElement initialElement) {
PsiElement element1 = file.getViewProvider().findElementAt(startOffset, language);
PsiElement element2 = file.getViewProvider().findElementAt(endOffset - 1, language);
if (element1 instanceof PsiWhiteSpace) {
startOffset = element1.getTextRange().getEndOffset();
element1 = file.getViewProvider().findElementAt(startOffset, language);
}
if (element2 instanceof PsiWhiteSpace) {
endOffset = element2.getTextRange().getStartOffset();
element2 = file.getViewProvider().findElementAt(endOffset - 1, language);
}
if (element2 == null || element1 == null) return null;
final PsiElement commonParent = PsiTreeUtil.findCommonParent(element1, element2);
final T element =
ReflectionUtil.isAssignable(klass, commonParent.getClass())
? (T)commonParent : PsiTreeUtil.getParentOfType(commonParent, klass);
if (element == initialElement) {
return element;
}
if (element == null || element.getTextRange().getStartOffset() != startOffset || element.getTextRange().getEndOffset() != endOffset) {
return null;
}
return element;
}
@Nonnull
private static String getCommandText(@Nonnull Project project, @Nonnull Editor editor) {
TextRange selectedRange = EditorUtil.getSelectionInAnyMode(editor);
Document document = editor.getDocument();
if (selectedRange.isEmpty()) {
int line = document.getLineNumber(selectedRange.getStartOffset());
selectedRange = TextRange.create(document.getLineStartOffset(line), document.getLineEndOffset(line));
// try detect a non-trivial composite PSI element if there's a PSI file
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
if (file != null && file.getFirstChild() != null && file.getFirstChild() != file.getLastChild()) {
PsiElement e1 = file.findElementAt(selectedRange.getStartOffset());
PsiElement e2 = file.findElementAt(selectedRange.getEndOffset());
while (e1 != e2 && (e1 instanceof PsiWhiteSpace || e1 != null && StringUtil.isEmptyOrSpaces(e1.getText()))) {
e1 = ObjectUtils.chooseNotNull(e1.getNextSibling(), PsiTreeUtil.getDeepestFirst(e1.getParent()));
}
while (e1 != e2 && (e2 instanceof PsiWhiteSpace || e2 != null && StringUtil.isEmptyOrSpaces(e2.getText()))) {
e2 = ObjectUtils.chooseNotNull(e2.getPrevSibling(), PsiTreeUtil.getDeepestLast(e2.getParent()));
}
if (e1 instanceof LeafPsiElement) e1 = e1.getParent();
if (e2 instanceof LeafPsiElement) e2 = e2.getParent();
PsiElement parent = e1 == null ? e2 : e2 == null ? e1 : PsiTreeUtil.findCommonParent(e1, e2);
if (parent != null && parent != file) {
selectedRange = parent.getTextRange();
}
}
}
return document.getText(selectedRange);
}
@Nullable
protected PsiElement checkLocalScope() {
final SearchScope searchScope = PsiSearchHelper.SERVICE.getInstance(myElementToRename.getProject()).getUseScope(myElementToRename);
if (searchScope instanceof LocalSearchScope) {
final PsiElement[] elements = ((LocalSearchScope)searchScope).getScope();
return PsiTreeUtil.findCommonParent(elements);
}
return null;
}
@Override
@RequiredReadAction
public boolean checkAvailable(@Nonnull final Editor editor, @Nonnull final PsiFile file, @Nonnull final MoveInfo info, final boolean down)
{
if(!(file instanceof CSharpFile))
{
return false;
}
boolean available = super.checkAvailable(editor, file, info, down);
if(!available)
{
return false;
}
LineRange oldRange = info.toMove;
final Pair<PsiElement, PsiElement> psiRange = getElementRange(editor, file, oldRange);
if(psiRange == null)
{
return false;
}
final DotNetNamedElement firstMember = PsiTreeUtil.getParentOfType(psiRange.getFirst(), DotNetNamedElement.class, false);
final DotNetNamedElement lastMember = PsiTreeUtil.getParentOfType(psiRange.getSecond(), DotNetNamedElement.class, false);
if(firstMember == null || lastMember == null)
{
return false;
}
LineRange range;
if(firstMember == lastMember)
{
range = memberRange(firstMember, editor, oldRange);
if(range == null)
{
return false;
}
range.firstElement = range.lastElement = firstMember;
}
else
{
final PsiElement parent = PsiTreeUtil.findCommonParent(firstMember, lastMember);
if(parent == null)
{
return false;
}
final Pair<PsiElement, PsiElement> combinedRange = getElementRange(parent, firstMember, lastMember);
if(combinedRange == null)
{
return false;
}
final LineRange lineRange1 = memberRange(combinedRange.getFirst(), editor, oldRange);
if(lineRange1 == null)
{
return false;
}
final LineRange lineRange2 = memberRange(combinedRange.getSecond(), editor, oldRange);
if(lineRange2 == null)
{
return false;
}
range = new LineRange(lineRange1.startLine, lineRange2.endLine);
range.firstElement = combinedRange.getFirst();
range.lastElement = combinedRange.getSecond();
}
Document document = editor.getDocument();
PsiElement sibling = down ? range.lastElement.getNextSibling() : range.firstElement.getPrevSibling();
if(sibling == null)
{
return false;
}
sibling = firstNonWhiteElement(sibling, down);
final boolean areWeMovingClass = range.firstElement instanceof CSharpTypeDeclaration;
info.toMove = range;
try
{
LineRange intraClassRange = moveInsideOutsideClassPosition(editor, sibling, down, areWeMovingClass);
if(intraClassRange == null)
{
info.toMove2 = new LineRange(sibling, sibling, document);
if(down && sibling.getNextSibling() == null)
{
return false;
}
}
else
{
info.toMove2 = intraClassRange;
}
}
catch(IllegalMoveException e)
{
info.toMove2 = null;
}
return true;
}
public static PsiElement[] findStatementsInRange(PsiFile file, int startOffset, int endOffset)
{
PsiElement element1 = file.findElementAt(startOffset);
PsiElement element2 = file.findElementAt(endOffset - 1);
if(element1 instanceof PsiWhiteSpace)
{
startOffset = element1.getTextRange().getEndOffset();
element1 = file.findElementAt(startOffset);
}
if(element2 instanceof PsiWhiteSpace)
{
endOffset = element2.getTextRange().getStartOffset();
element2 = file.findElementAt(endOffset - 1);
}
if(element1 != null && element2 != null)
{
PsiElement commonParent = PsiTreeUtil.findCommonParent(element1, element2);
if(commonParent instanceof DotNetExpression)
{
return new PsiElement[]{commonParent};
}
}
final DotNetStatement statements = PsiTreeUtil.getParentOfType(element1, DotNetStatement.class);
if(statements == null || element1 == null || element2 == null || !PsiTreeUtil.isAncestor(statements, element2, true))
{
return PsiElement.EMPTY_ARRAY;
}
// don't forget about leafs (ex. ';')
final ASTNode[] astResult = UsefulPsiTreeUtil.findChildrenRange(statements.getNode().getChildren(null), startOffset, endOffset);
return ContainerUtil.map2Array(astResult, PsiElement.class, new Function<ASTNode, PsiElement>()
{
@Override
public PsiElement fun(ASTNode node)
{
return node.getPsi();
}
});
}