PY-34617 Support version check

GitOrigin-RevId: 3318ff79cdcc5ba0ce5e4feb65abad5ad0f4acfa
This commit is contained in:
Petr
2024-07-26 22:12:08 +02:00
committed by intellij-monorepo-bot
parent 16a7fb4b3e
commit 93b9066edf
60 changed files with 1086 additions and 219 deletions

View File

@@ -2,7 +2,10 @@
package com.jetbrains.python.ast;
import com.intellij.lang.ASTNode;
import com.intellij.psi.*;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNameIdentifierOwner;
import com.intellij.psi.TokenType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayFactory;
import com.intellij.util.ArrayUtil;
@@ -11,9 +14,9 @@ import com.jetbrains.python.PyElementTypes;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.PythonDialectsTokenSetProvider;
import com.jetbrains.python.ast.impl.PyUtilCore;
import com.jetbrains.python.ast.controlFlow.AstScopeOwner;
import com.jetbrains.python.ast.docstring.DocStringUtilCore;
import com.jetbrains.python.ast.impl.PyUtilCore;
import com.jetbrains.python.psi.LanguageLevel;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@@ -28,7 +31,7 @@ import java.util.Optional;
@ApiStatus.Experimental
public interface PyAstFunction extends PsiNameIdentifierOwner, PyAstCompoundStatement,
PyAstDecoratable, PyAstCallable, PyAstStatementListContainer, PyAstPossibleClassMember,
AstScopeOwner, PyAstDocStringOwner, PyAstTypeCommentOwner, PyAstAnnotationOwner, PyAstTypeParameterListOwner{
AstScopeOwner, PyAstDocStringOwner, PyAstTypeCommentOwner, PyAstAnnotationOwner, PyAstTypeParameterListOwner {
PyAstFunction[] EMPTY_ARRAY = new PyAstFunction[0];
ArrayFactory<PyAstFunction> ARRAY_FACTORY = count -> count == 0 ? EMPTY_ARRAY : new PyAstFunction[count];
@@ -231,7 +234,7 @@ public interface PyAstFunction extends PsiNameIdentifierOwner, PyAstCompoundStat
@Override
@Nullable
default PyAstClass getContainingClass() {
final PsiElement parent = PsiTreeUtil.getParentOfType(this, StubBasedPsiElement.class);
final PsiElement parent = PsiTreeUtil.getParentOfType(this, AstScopeOwner.class);
if (parent instanceof PyAstClass) {
return (PyAstClass)parent;
}

View File

@@ -17,7 +17,6 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -80,43 +79,6 @@ public final class PyPsiUtilsCore {
return null;
}
@ApiStatus.Internal
@NotNull
public static <T extends PyAstElement> List<T> collectChildren(@NotNull PyAstFile pyFile, @NotNull Class<T> elementType) {
final List<T> result = new ArrayList<>();
pyFile.acceptChildren(new TopLevelVisitor() {
@Override
protected void checkAddElement(PsiElement node) {
if (elementType.isInstance(node)) {
result.add(elementType.cast(node));
}
}
@Override
public void visitPyStatement(@NotNull PyAstStatement node) {
if (PyAstStatement.class.isAssignableFrom(elementType) && !(node instanceof PyAstCompoundStatement)) {
checkAddElement(node);
return;
}
super.visitPyStatement(node);
}
});
return result;
}
@ApiStatus.Internal
@NotNull
public static List<PsiElement> collectAllChildren(PsiElement e) {
final List<PsiElement> result = new ArrayList<>();
e.acceptChildren(new TopLevelVisitor() {
@Override
protected void checkAddElement(PsiElement node) {
result.add(node);
}
});
return result;
}
/**
* Returns the first non-whitespace sibling following the given element but within its line boundaries.
*/
@@ -135,26 +97,6 @@ public final class PyPsiUtilsCore {
return null;
}
private static abstract class TopLevelVisitor extends PyAstRecursiveElementVisitor {
@Override
public void visitPyElement(final @NotNull PyAstElement node) {
super.visitPyElement(node);
checkAddElement(node);
}
@Override
public void visitPyClass(final @NotNull PyAstClass node) {
checkAddElement(node); // do not recurse into functions
}
@Override
public void visitPyFunction(final @NotNull PyAstFunction node) {
checkAddElement(node); // do not recurse into classes
}
protected abstract void checkAddElement(PsiElement node);
}
@Nullable
public static String strValue(@Nullable PyAstExpression expression) {
return expression instanceof PyAstStringLiteralExpression ? ((PyAstStringLiteralExpression)expression).getStringValue() : null;
@@ -198,4 +140,12 @@ public final class PyPsiUtilsCore {
}
PsiUtilCore.ensureValid(element);
}
@Nullable
public static PyAstExpression flattenParens(@Nullable PyAstExpression expr) {
while (expr instanceof PyAstParenthesizedExpression) {
expr = ((PyAstParenthesizedExpression)expr).getContainedExpression();
}
return expr;
}
}

View File

@@ -26,7 +26,6 @@ import java.util.regex.Pattern;
/**
* Assorted utility methods for Python code insight.
*
* These methods don't depend on the Python runtime.
*
* @see PyPsiUtilsCore for utilities used in Python PSI API
@@ -99,11 +98,13 @@ public final class PyUtilCore {
public static boolean isTopLevel(@NotNull PsiElement element) {
if (element instanceof StubBasedPsiElement) {
final StubElement stub = ((StubBasedPsiElement<?>)element).getStub();
final StubElement<?> stub = ((StubBasedPsiElement<?>)element).getStub();
if (stub != null) {
final StubElement parentStub = stub.getParentStub();
if (parentStub != null) {
return parentStub.getPsi() instanceof PsiFile;
for (StubElement<?> parentStub = stub.getParentStub(); parentStub != null; parentStub = parentStub.getParentStub()) {
PsiElement psi = parentStub.getPsi();
if (!(psi instanceof PyAstIfPart || psi instanceof PyAstElsePart)) {
return psi instanceof PsiFile;
}
}
}
}