下面列出了com.intellij.psi.PsiElement#getPrevSibling ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@RequiredReadAction
private static PsiElement findLastComment(PsiElement element, IElementType elementType)
{
PsiElement target = element;
PsiElement nextSibling = element.getNextSibling();
while(nextSibling != null)
{
if(isAcceptableComment(nextSibling, elementType))
{
if(nextSibling instanceof PsiWhiteSpace)
{
target = nextSibling.getPrevSibling();
}
else
{
target = nextSibling;
}
nextSibling = nextSibling.getNextSibling();
}
else
{
return target;
}
}
return element;
}
@SuppressWarnings("ConstantConditions")
@Nullable
private static TextRange getFileHeader(PsiElement file) {
PsiElement first = file.getFirstChild();
if (first instanceof PsiWhiteSpace) first = first.getNextSibling();
PsiElement element = first;
while (isComment(element)) {
element = element.getNextSibling();
if (element instanceof PsiWhiteSpace) {
element = element.getNextSibling();
} else {
break;
}
}
if (element == null) return null;
if (element.getPrevSibling() instanceof PsiWhiteSpace) element = element.getPrevSibling();
if (element == null || element.equals(first)) return null;
return new UnfairTextRange(first.getTextOffset(), element.getTextOffset());
}
@Nullable
@RequiredReadAction
public static DotNetModifierListOwner findOwner(@Nonnull PsiElement element)
{
PsiElement parent = element.getParent();
if(element instanceof CSharpIdentifier && parent instanceof DotNetModifierListOwner)
{
return (DotNetModifierListOwner) parent;
}
if(parent instanceof CSharpIdentifier && parent.getParent() instanceof DotNetModifierListOwner)
{
return (DotNetModifierListOwner) parent.getParent();
}
PsiElement prevSibling = element.getPrevSibling();
if(prevSibling instanceof CSharpIdentifier && prevSibling.getParent() instanceof DotNetModifierListOwner)
{
return (DotNetModifierListOwner) prevSibling.getParent();
}
return null;
}
@Nonnull
@Override
public PsiElement[] getElementsToSurround(PsiFile file, int startOffset, int endOffset) {
if (startOffset >= endOffset - 1) return PsiElement.EMPTY_ARRAY;
Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(file.getLanguage());
if (commenter == null || commenter.getLineCommentPrefix() == null) return PsiElement.EMPTY_ARRAY;
PsiElement startElement = file.findElementAt(startOffset);
if (startElement instanceof PsiWhiteSpace) startElement = startElement.getNextSibling();
PsiElement endElement = file.findElementAt(endOffset - 1);
if (endElement instanceof PsiWhiteSpace) endElement = endElement.getPrevSibling();
if (startElement != null && endElement != null) {
if (startElement.getTextRange().getStartOffset() > endElement.getTextRange().getStartOffset()) return PsiElement.EMPTY_ARRAY;
startElement = findClosestParentAfterLineBreak(startElement);
if (startElement != null) {
endElement = findClosestParentBeforeLineBreak(endElement);
if (endElement != null) {
PsiElement commonParent = startElement.getParent();
if (endElement.getParent() == commonParent) {
if (startElement == endElement) return new PsiElement[] {startElement};
return new PsiElement[] {startElement, endElement};
}
}
}
}
return PsiElement.EMPTY_ARRAY;
}
@Override
public Optional<String> extractTextFromElement(PsiElement element, boolean concatString, boolean stripWhitespace) {
// maybe its xml then try that
if (element instanceof XmlAttributeValue) {
return Optional.ofNullable(((XmlAttributeValue) element).getValue());
} else if (element instanceof XmlText) {
return Optional.ofNullable(((XmlText) element).getValue());
} else if (element instanceof XmlToken) {
// it may be a token which is a part of an combined attribute
if (concatString) {
XmlAttributeValue xml = PsiTreeUtil.getParentOfType(element, XmlAttributeValue.class);
if (xml != null) {
return Optional.ofNullable(getInnerText(xml.getValue()));
}
} else {
String returnText = element.getText();
final PsiElement prevSibling = element.getPrevSibling();
if (prevSibling != null && prevSibling.getText().equalsIgnoreCase("&")) {
returnText = prevSibling.getText() + returnText;
}
return Optional.ofNullable(getInnerText(returnText));
}
}
return Optional.empty();
}
@Override
public void visitElement(PsiElement element) {
if(element instanceof BladePsiDirectiveParameter) {
PsiElement sectionElement = element.getPrevSibling();
if(sectionElement.getNode().getElementType() == this.directiveElementType) {
for(PsiElement psiElement : PsiElementUtils.getChildrenFix(element)) {
if(psiElement.getNode().getElementType() == BladeTokenTypes.DIRECTIVE_PARAMETER_CONTENT) {
String content = PsiElementUtils.trimQuote(psiElement.getText());
if(StringUtils.isNotBlank(content)) {
map.put(content, null);
}
}
}
}
}
super.visitElement(element);
}
/**
* "\My\Bar::cla<caret>ss" => "\My\Bar"
*/
@Nullable
public static PhpClass getClassFromConstant(@NotNull PsiElement psiElement) {
PsiElement prevSibling = psiElement.getPrevSibling();
if (prevSibling == null || !de.espend.idea.php.annotation.util.PhpDocUtil.isDocStaticElement(prevSibling)) {
return null;
}
PsiElement prevSibling1 = prevSibling.getPrevSibling();
if (prevSibling1 == null || prevSibling1.getNode().getElementType() != PhpDocTokenTypes.DOC_IDENTIFIER) {
return null;
}
return getClassFromDocIdentifier(prevSibling1);
}
public boolean isDefineFirstCollection(PsiElement element) {
PsiElement jsArrayLiteral = element.getParent();
if (null != jsArrayLiteral && jsArrayLiteral instanceof JSArrayLiteralExpression) {
PsiElement jsArgumentList = jsArrayLiteral.getParent();
if (null != jsArgumentList && jsArgumentList instanceof JSArgumentList) {
PsiElement jsReferenceExpression = jsArgumentList.getPrevSibling();
if (null != jsReferenceExpression && jsReferenceExpression instanceof JSReferenceExpression) {
if (jsReferenceExpression.getText().equals(Settings.REQUIREJS_DEFINE_FUNCTION_NAME)) {
return true;
}
}
}
}
return false;
}
@NotNull
protected String extractPathName(@NotNull PsiElement element, @NotNull ORTypes types) {
String path = "";
PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(element);
if (prevLeaf != null && prevLeaf.getNode().getElementType() == types.DOT) {
// Extract the qualified name of current element
PsiElement prevSibling = prevLeaf.getPrevSibling();
if (prevSibling instanceof PsiNamedElement) {
String name = ((PsiNamedElement) prevSibling).getName();
path = name == null ? "" : name;
prevSibling = prevSibling.getPrevSibling();
}
while (prevSibling != null && prevSibling.getNode().getElementType() == types.DOT) {
prevSibling = prevSibling.getPrevSibling();
if (prevSibling instanceof PsiNamedElement) {
path = ((PsiNamedElement) prevSibling).getName() + "." + path;
prevSibling = prevSibling.getPrevSibling();
} else {
break;
}
}
}
return path;
}
@Nullable
private PsiElement findAboveComment(@Nullable PsiElement element) {
if (element == null) {
return null;
}
PsiElement prevSibling = element.getPrevSibling();
PsiElement prevPrevSibling = prevSibling == null ? null : prevSibling.getPrevSibling();
if (prevPrevSibling instanceof PsiComment && prevSibling instanceof PsiWhiteSpace && prevSibling.getText().replaceAll("[ \t]", "").length() == 1) {
return prevPrevSibling;
}
return null;
}
private static @Nullable PsiElement previousInTree(PsiElement element) {
PsiElement sibling = element.getPrevSibling();
if (sibling != null) {
return deepLast(sibling);
}
PsiElement parent = element.getParent();
if (parent != null) {
return previousInTree(parent);
}
return null;
}
public static JSLiteralExpression getNearestLiteralExpression(PsiElement element, Direction direction)
{
PsiElement node = element;
if(direction == Direction.UP)
{
node = element.getPrevSibling();
}
else
{
node = element.getNextSibling();
}
int tries = 0;
while(tries < 5)
{
if(node instanceof JSLiteralExpression)
{
return (JSLiteralExpression) node;
}
if(node == null)
{
return null;
}
if(direction == Direction.UP)
{
node = node.getPrevSibling();
}
else
{
node = node.getNextSibling();
}
tries ++;
}
return null;
}
private GLSLDefineDirective resolveDeeperIn(PsiElement current){
while(current != null){
if (current instanceof GLSLDefineDirective) {
GLSLDefineDirective directive = (GLSLDefineDirective) current;
if (source.getName().equals(directive.getName())) return directive;
}else{
final GLSLDefineDirective deeper = resolveDeeperIn(current.getLastChild());
if(deeper != null)return deeper;
}
current = current.getPrevSibling();
}
return null;
}
private void addModuleCompletions(PsiElement element, CompletionResultSet resultSet) {
PsiElement prevSibling = element.getPrevSibling();
PsiElement prevPrevSibling = Optional.ofNullable(prevSibling)
.flatMap(e -> Optional.ofNullable(e.getPrevSibling()))
.orElse(null);
if (!isElementOfType(prevSibling, ElmTypes.DOT)) {
return;
}
if (prevPrevSibling instanceof ElmUpperCaseId) {
addCompletionsAfterDot(prevSibling, resultSet);
} else if (prevPrevSibling instanceof ElmLowerCaseId) {
this.recordFieldsProvider.addCompletions((ElmFile) element.getContainingFile(), resultSet);
}
}
private void addCompletionsInInvalidExpression(@NotNull PsiElement position, @NotNull CompletionResultSet resultSet) {
PsiElement prevSibling = position.getPrevSibling();
if (isAfterLowerCaseOrWhiteSpace(position)) {
this.recordFieldsProvider.addCompletions((ElmFile) position.getContainingFile(), resultSet);
} else if (prevSibling == null) {
this.keywordsProvider.addCompletions(resultSet);
} else if (prevSibling instanceof PsiWhiteSpace) {
addCompletionsAfterWhiteSpace(position, resultSet);
} else if (prevSibling instanceof ASTNode) {
addCompletionsAfterASTNode((ASTNode) prevSibling, resultSet);
}
}
@Nullable
public GLSLExpression getCondition() {
PsiElement condition = findChildByType(QUESTION);
while (condition != null && !(condition instanceof GLSLExpression)) {
condition = condition.getPrevSibling();
}
return (GLSLExpression) condition;
}
private static boolean insertIndent(PsiFile file, int offset) {
if (offset == 0) {
return false;
}
PsiElement element = file.findElementAt(offset - 1);
while (element != null && element instanceof PsiWhiteSpace) {
element = element.getPrevSibling();
}
if (element == null || element.getText() != ":") {
return false;
}
ASTNode prev = element.getNode().getTreePrev();
return prev != null && prev.getElementType() == ProjectViewTokenType.LIST_KEYWORD;
}
@Nullable
public static <T extends PsiElement> T getPrevSiblingOfType(@Nullable PsiElement sibling, ElementPattern<T> pattern) {
if (sibling == null) return null;
for (PsiElement child = sibling.getPrevSibling(); child != null; child = child.getPrevSibling()) {
if (pattern.accepts(child)) {
//noinspection unchecked
return (T) child;
}
}
return null;
}
@Override
public int getStartOffset() {
PsiElement prevSibling = getPrevSibling();
while (prevSibling != null) {
if (prevSibling.getText().equals(":")) {
return prevSibling.getNode().getStartOffset() + 1;
}
prevSibling = prevSibling.getPrevSibling();
}
return getNode().getStartOffset();
}
/**
* when the user adds a new import, this code searches for the nearest possible element
* to the cursor that they may have wanted to import and returns a suggested choice.
*
* I know this method is crude/hard to read and could be way more elegant, however it's good enough for now
* and produces quite a lot of benefit for low effort
*
* TODO this is a good candidate for unit testing...
*/
public String getSuggestedImport(@Nullable PsiElement element)
{
if(element == null)
{
return "";
}
String initialChoice = "";
PsiElement parent = element.getParent();
PsiElement previousSibling = element.getPrevSibling();
// (underscore represents cursor)
// we're just over a reference. Example: Site_Util
if (element.getParent() != null && element.getParent() instanceof JSReferenceExpression)
{
initialChoice = element.getText();
}
// we're inside a constructor. Example: new Button({_});
if(element.getParent() instanceof JSObjectLiteralExpression)
{
JSObjectLiteralExpression literal = (JSObjectLiteralExpression) element.getParent();
if(literal.getParent() != null && literal.getParent().getParent() != null && literal.getParent().getParent() instanceof JSNewExpression)
{
initialChoice = ((JSNewExpression)literal.getParent().getParent()).getMethodExpression().getText();
}
}
// we're inside a new expression Example: new Button_
if(parent != null && element.getParent().getParent() != null && parent.getParent() instanceof JSNewExpression)
{
initialChoice = ((JSNewExpression)parent.getParent()).getMethodExpression().getText();
}
// we're right after a new expression. Example: new Button({}) _
else if (previousSibling != null && previousSibling.getChildren().length > 0 && previousSibling.getChildren()[0] instanceof JSNewExpression)
{
initialChoice = ((JSNewExpression)previousSibling.getChildren()[0]).getMethodExpression().getText();
}
// right after a reference. Example: SiteUtil_
else if (previousSibling != null && previousSibling.getChildren().length > 0 && previousSibling.getChildren()[0] instanceof JSReferenceExpression)
{
initialChoice = previousSibling.getChildren()[0].getText();
}
// after a variable declaration. Example: var x = new Button({})_
else if (previousSibling != null && element.getPrevSibling() instanceof JSVarStatement)
{
JSVarStatement statement = (JSVarStatement) element.getPrevSibling();
for(JSVariable variable : statement.getVariables())
{
if(variable.getInitializer() instanceof JSNewExpression)
{
JSNewExpression expression = (JSNewExpression) variable.getInitializer();
// if these conditions are false, it just means the new expression is not complete
if(expression != null && expression.getMethodExpression() != null)
{
initialChoice = expression.getMethodExpression().getText();
}
}
}
}
return initialChoice;
}