PY-85271 Reformat files with incorrect formatting

GitOrigin-RevId: 6c8ee5d2ca5f5807c6534e8a97843d16371562d8
This commit is contained in:
evgeny.bovykin
2025-11-13 16:49:09 +00:00
committed by intellij-monorepo-bot
parent c1e6f78373
commit d7e26c8bc1
391 changed files with 2125 additions and 1459 deletions
@@ -17,7 +17,7 @@ public enum PythonFunctionParameters implements FunctionParameter {
/**
* environment.setdevault(key, failobj) # failobj
*/
ENV_SET_DEFAULT_FAILOBJ("failobj",1);
ENV_SET_DEFAULT_FAILOBJ("failobj", 1);
private final @Nullable String myName;
@@ -216,7 +216,8 @@ public class PyCustomMember extends UserDataHolderBase {
targetClass = (PyClass)resolveTarget;
}
return PyCustomMemberProvider.getInstance().createPyCustomMemberTarget(this, targetClass, context, resolveTarget, myTypeCallback, myCustomTypeInfo, myResolveToInstance);
return PyCustomMemberProvider.getInstance()
.createPyCustomMemberTarget(this, targetClass, context, resolveTarget, myTypeCallback, myCustomTypeInfo, myResolveToInstance);
}
return null;
}
@@ -284,5 +285,4 @@ public class PyCustomMember extends UserDataHolderBase {
myCustomTypeInfo = customInfo;
return this;
}
}
@@ -64,7 +64,7 @@ public abstract class PyPsiPath {
return null;
}
if (parent instanceof PyFile) {
return ((PyFile) parent).findTopLevelClass(myClassName);
return ((PyFile)parent).findTopLevelClass(myClassName);
}
if (resolveContext.getTypeEvalContext().maySwitchToAST(parent)) {
if (parent instanceof PyClass) {
@@ -115,10 +115,10 @@ public abstract class PyPsiPath {
return null;
}
if (parent instanceof PyFile) {
return ((PyFile) parent).findTopLevelFunction(myFunctionName);
return ((PyFile)parent).findTopLevelFunction(myFunctionName);
}
if (parent instanceof PyClass) {
return ((PyClass) parent).findMethodByName(myFunctionName, false, resolveContext.getTypeEvalContext());
return ((PyClass)parent).findMethodByName(myFunctionName, false, resolveContext.getTypeEvalContext());
}
if (resolveContext.getTypeEvalContext().maySwitchToAST(parent)) {
for (PsiElement element : parent.getChildren()) {
@@ -230,14 +230,14 @@ public abstract class PyPsiPath {
final PyExpression callee = node.getCallee();
if (callee instanceof PyReferenceExpression) {
final String calleeName = ((PyReferenceExpression) callee).getReferencedName();
final String calleeName = ((PyReferenceExpression)callee).getReferencedName();
if (myCallName.equals(calleeName)) {
final PyExpression[] args = node.getArguments();
if (myArgs.length <= args.length) {
boolean argsMatch = true;
for (int i = 0; i < myArgs.length; i++) {
if (!(args[i] instanceof PyStringLiteralExpression) ||
!myArgs [i].equals(((PyStringLiteralExpression)args[i]).getStringValue())) {
!myArgs[i].equals(((PyStringLiteralExpression)args[i]).getStringValue())) {
argsMatch = false;
break;
}
@@ -58,6 +58,7 @@ public abstract class PyInspectionExtension {
/**
* Enable "unresolved reference" inspection regardless of IDE type and initialized SDK.
*
* @return true -- Enable forcibly, false -- disable forcibly, null -- act as usual.
*/
public Boolean overrideUnresolvedReferenceInspection(@NotNull PsiFile file) {
@@ -124,5 +125,5 @@ public abstract class PyInspectionExtension {
/**
* @return Do not report "unused import"
*/
public boolean ignoreUnusedImports(@NotNull PyImportedNameDefiner importNameDefiner) {return false;}
public boolean ignoreUnusedImports(@NotNull PyImportedNameDefiner importNameDefiner) { return false; }
}
@@ -109,7 +109,8 @@ public final class NameResolverTools {
* @param functionName function to find
* @return parent call or null if not found
*/
public static @Nullable PyCallExpression findCallExpParent(final @NotNull PsiElement anchor, final @NotNull FQNamesProvider functionName) {
public static @Nullable PyCallExpression findCallExpParent(final @NotNull PsiElement anchor,
final @NotNull FQNamesProvider functionName) {
final PsiElement parent = PsiTreeUtil.findFirstParent(anchor, new MyFunctionCondition(functionName));
if (parent instanceof PyCallExpression) {
return (PyCallExpression)parent;
@@ -151,7 +152,7 @@ public final class NameResolverTools {
/**
* Checks if some string contains last component one of name
*
* @param text test to check
* @param text test to check
*/
public static boolean isContainsName(final @NotNull String text, final @NotNull FQNamesProvider names) {
for (final String lastComponent : getLastComponents(names)) {
@@ -165,7 +166,7 @@ public final class NameResolverTools {
/**
* Checks if some file contains last component one of name
*
* @param file file to check
* @param file file to check
*/
public static boolean isContainsName(final @NotNull PsiFile file, final @NotNull FQNamesProvider names) {
return isContainsName(file.getText(), names);
@@ -24,5 +24,8 @@ import org.jetbrains.annotations.Nullable;
public interface PsiReferenceEx extends PsiReference {
@Nullable
HighlightSeverity getUnresolvedHighlightSeverity(TypeEvalContext context);
@Nullable @Nls String getUnresolvedDescription();
@Nullable
@Nls
String getUnresolvedDescription();
}
@@ -65,6 +65,7 @@ public interface PyAssignmentStatement extends PyAstAssignmentStatement, PyState
* <br/>
* If RHS and LHS are mis-balanced, certain target or value expressions may be null.
* If source is severely incorrect, the returned mapping is empty.
*
* @return a list of [target, value] pairs; either part of a pair may be null, but not both.
*/
@Override
@@ -77,5 +78,4 @@ public interface PyAssignmentStatement extends PyAstAssignmentStatement, PyState
default @Nullable PyExpression getLeftHandSideExpression() {
return (PyExpression)PyAstAssignmentStatement.super.getLeftHandSideExpression();
}
}
@@ -25,9 +25,10 @@ import java.util.Map;
/**
* Represents a class declaration in source.
*/
public interface PyClass extends PyAstClass, PsiNameIdentifierOwner, PyCompoundStatement, PyDocStringOwner, StubBasedPsiElement<PyClassStub>,
ScopeOwner, PyDecoratable, PyTypedElement, PyQualifiedNameOwner, PyStatementListContainer, PyWithAncestors,
PyTypeParameterListOwner, PyDeprecatable {
public interface PyClass
extends PyAstClass, PsiNameIdentifierOwner, PyCompoundStatement, PyDocStringOwner, StubBasedPsiElement<PyClassStub>,
ScopeOwner, PyDecoratable, PyTypedElement, PyQualifiedNameOwner, PyStatementListContainer, PyWithAncestors,
PyTypeParameterListOwner, PyDeprecatable {
PyClass[] EMPTY_ARRAY = new PyClass[0];
ArrayFactory<PyClass> ARRAY_FACTORY = count -> count == 0 ? EMPTY_ARRAY : new PyClass[count];
@@ -9,7 +9,7 @@ import java.util.Set;
public interface PyClassPattern extends PyAstClassPattern, PyPattern {
Set<String> SPECIAL_BUILTINS = Set.of(
"bool", "bytearray", "bytes", "dict", "float", "frozenset", "int", "list", "set", "str", "tuple");
@Override
default @NotNull PyReferenceExpression getClassNameReference() {
return (PyReferenceExpression)PyAstClassPattern.super.getClassNameReference();
@@ -23,5 +23,4 @@ public interface PyElement extends PyAstElement {
* An empty array to return cheaply without allocating it anew.
*/
PyElement[] EMPTY_ARRAY = new PyElement[0];
}
@@ -30,15 +30,15 @@ public abstract class PyElementGenerator extends PyAstElementGenerator {
/**
* Creates a string literal, adding appropriate quotes, properly escaping characters inside.
*
* @param destination where the literal is destined to; used to determine the encoding.
* @param unescaped the string
* @param preferUTF8 try to use UTF8 (would use ascii if false)
* @param destination where the literal is destined to; used to determine the encoding.
* @param unescaped the string
* @param preferUTF8 try to use UTF8 (would use ascii if false)
* @param preferDoubleQuotes try to use double/single quotes
* @return a newly created literal
*/
protected abstract PyStringLiteralExpression createStringLiteralFromString(@Nullable PsiFile destination,
@NotNull String unescaped,
boolean preferUTF8, boolean preferDoubleQuotes);
@NotNull String unescaped,
boolean preferUTF8, boolean preferDoubleQuotes);
public abstract PyStringLiteralExpression createStringLiteralFromString(@NotNull String unescaped, boolean preferDoubleQuotes);
@@ -55,11 +55,13 @@ public abstract class PyElementGenerator extends PyAstElementGenerator {
@NotNull PyExpression rightOperand);
@Override
public @NotNull PyExpression createExpressionFromText(@NotNull LanguageLevel languageLevel, @NotNull String text) throws IncorrectOperationException {
public @NotNull PyExpression createExpressionFromText(@NotNull LanguageLevel languageLevel, @NotNull String text)
throws IncorrectOperationException {
return (PyExpression)super.createExpressionFromText(languageLevel, text);
}
public abstract @NotNull PyPattern createPatternFromText(@NotNull LanguageLevel languageLevel, @NotNull String text) throws IncorrectOperationException;
public abstract @NotNull PyPattern createPatternFromText(@NotNull LanguageLevel languageLevel, @NotNull String text)
throws IncorrectOperationException;
/**
* Adds elements to list inserting required commas.
@@ -131,9 +133,9 @@ public abstract class PyElementGenerator extends PyAstElementGenerator {
* @return created {@link PyFromImportStatement}
*/
public abstract @NotNull PyFromImportStatement createFromImportStatement(@NotNull LanguageLevel languageLevel,
@NotNull String qualifier,
@NotNull String name,
@Nullable String alias);
@NotNull String qualifier,
@NotNull String name,
@Nullable String alias);
/**
* Creates import statement of form {@code import name as alias}.
@@ -144,8 +146,8 @@ public abstract class PyElementGenerator extends PyAstElementGenerator {
* @return created {@link PyImportStatement}
*/
public abstract @NotNull PyImportStatement createImportStatement(@NotNull LanguageLevel languageLevel,
@NotNull String name,
@Nullable String alias);
@NotNull String name,
@Nullable String alias);
public abstract @NotNull PyEllipsisLiteralExpression createEllipsis();
@@ -6,7 +6,8 @@ import com.jetbrains.python.ast.PyAstExceptPart;
import com.jetbrains.python.psi.stubs.PyExceptPartStub;
import org.jetbrains.annotations.Nullable;
public interface PyExceptPart extends PyAstExceptPart, PyElement, StubBasedPsiElement<PyExceptPartStub>, PyNamedElementContainer, PyStatementPart {
public interface PyExceptPart
extends PyAstExceptPart, PyElement, StubBasedPsiElement<PyExceptPartStub>, PyNamedElementContainer, PyStatementPart {
PyExceptPart[] EMPTY_ARRAY = new PyExceptPart[0];
@Override
@@ -23,5 +23,4 @@ public interface PyForPart extends PyAstForPart, PyStatementPart {
default @Nullable PyExpression getSource() {
return (PyExpression)PyAstForPart.super.getSource();
}
}
@@ -8,10 +8,10 @@ import java.util.List;
/**
* Represents an f-string, a special kind of interpolated string literal introduced in Python 3.6.
*
* <p>
* Unlike {@link PyPlainStringElement} these elements are composite and consist of several kinds of tokens
* and normal PSI trees for embedded expressions.
*
*
* @see com.jetbrains.python.PyTokenTypes#FSTRING_START
* @see com.jetbrains.python.PyTokenTypes#FSTRING_TEXT
* @see PyFStringFragment
@@ -14,10 +14,12 @@ import java.util.List;
/**
* Describes "from ... import" statements.
*/
public interface PyFromImportStatement extends PyAstFromImportStatement, PyImportStatementBase, StubBasedPsiElement<PyFromImportStatementStub>,
PyImplicitImportNameDefiner {
public interface PyFromImportStatement
extends PyAstFromImportStatement, PyImportStatementBase, StubBasedPsiElement<PyFromImportStatementStub>,
PyImplicitImportNameDefiner {
/**
* Returns a reference the module from which import is required.
*
* @return reference to module. If the 'from' reference is relative and consists entirely of dots, null is returned.
*/
@Override
@@ -41,9 +41,9 @@ public interface PyFunction extends PyAstFunction, StubBasedPsiElement<PyFunctio
/**
* Infers function's return type by analyzing <b>return statements</b> (including implicit returns) and <b>yield expression</b>.
* In contrast with {@link TypeEvalContext#getReturnType(PyCallable)} does not consider
* In contrast with {@link TypeEvalContext#getReturnType(PyCallable)} does not consider
* return type annotations or any other {@link PyTypeProvider}.
*
*
* @apiNote Does not cache the result.
*/
@ApiStatus.Internal
@@ -55,8 +55,8 @@ public interface PyFunction extends PyAstFunction, StubBasedPsiElement<PyFunctio
* This includes explicit 'return' statements and statements that can complete
* normally with an implicit 'return None', excluding statements that raise exceptions.
*
* @see PyFunction#getReturnStatementType(TypeEvalContext)
* @return List of exit point statements, in control flow order
* @see PyFunction#getReturnStatementType(TypeEvalContext)
*/
@ApiStatus.Internal
@NotNull
@@ -78,6 +78,7 @@ public interface PyFunction extends PyAstFunction, StubBasedPsiElement<PyFunctio
/**
* Searches for function attributes.
* See <a href="http://legacy.python.org/dev/peps/pep-0232/">PEP-0232</a>
*
* @return assignment statements for function attributes
*/
@NotNull
@@ -6,5 +6,6 @@ import com.jetbrains.python.ast.PyAstImportStatement;
import com.jetbrains.python.psi.stubs.PyImportStatementStub;
public interface PyImportStatement extends PyAstImportStatement, PyImportStatementBase, StubBasedPsiElement<PyImportStatementStub>, PyImplicitImportNameDefiner {
public interface PyImportStatement
extends PyAstImportStatement, PyImportStatementBase, StubBasedPsiElement<PyImportStatementStub>, PyImplicitImportNameDefiner {
}
@@ -7,7 +7,7 @@ import org.jetbrains.annotations.Nullable;
public interface PyKeyValueExpression extends PyAstKeyValueExpression, PyExpression {
PyKeyValueExpression[] EMPTY_ARRAY = new PyKeyValueExpression[0];
PyKeyValueExpression[] EMPTY_ARRAY = new PyKeyValueExpression[0];
@Override
default @NotNull PyExpression getKey() {
@@ -15,8 +15,9 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents a named parameter, as opposed to a tuple parameter.
*/
public interface PyNamedParameter extends PyAstNamedParameter, PyParameter, PsiNamedElement, PsiNameIdentifierOwner, PyExpression, PyTypeCommentOwner,
PyAnnotationOwner, StubBasedPsiElement<PyNamedParameterStub> {
public interface PyNamedParameter
extends PyAstNamedParameter, PyParameter, PsiNamedElement, PsiNameIdentifierOwner, PyExpression, PyTypeCommentOwner,
PyAnnotationOwner, StubBasedPsiElement<PyNamedParameterStub> {
@Override
default @Nullable PyExpression getDefaultValue() {
@@ -20,7 +20,8 @@ public abstract class PyPsiFacade {
return project.getService(PyPsiFacade.class);
}
public abstract @NotNull List<PsiElement> resolveQualifiedName(@NotNull QualifiedName name, @NotNull PyQualifiedNameResolveContext context);
public abstract @NotNull List<PsiElement> resolveQualifiedName(@NotNull QualifiedName name,
@NotNull PyQualifiedNameResolveContext context);
public abstract @NotNull PyQualifiedNameResolveContext createResolveContextFromFoothold(@NotNull PsiElement foothold);
@@ -16,5 +16,6 @@ public interface PyQualifiedNameOwner extends PyAstQualifiedNameOwner, PyElement
* is contained inside an element that doesn't have a qualified name.
*/
@Nullable
@NlsSafe String getQualifiedName();
@NlsSafe
String getQualifiedName();
}
@@ -43,7 +43,7 @@ public interface PyReferenceExpression extends PyAstReferenceExpression, PyQuali
* <i>Note: the returned list does not contain null values.</i>
*/
default @NotNull List<QualifiedRatedResolveResult> multiFollowAssignmentsChain(@NotNull PyResolveContext resolveContext) {
return multiFollowAssignmentsChain(resolveContext, __->true);
return multiFollowAssignmentsChain(resolveContext, __ -> true);
}
/**
@@ -51,7 +51,7 @@ public interface PyReferenceExpression extends PyAstReferenceExpression, PyQuali
* Starts at this, expecting it to resolve to a target of an assignment.
*
* @param resolveContext resolve context
* @param follow predicate to test if target should be followed
* @param follow predicate to test if target should be followed
* @return the values that could be assigned to this element via a chain of assignments, or an empty list.
* <i>Note: the returned list does not contain null values.</i>
*/
@@ -5,6 +5,6 @@ import com.jetbrains.python.ast.PyAstSequencePattern
import com.jetbrains.python.ast.findChildrenByClass
interface PySequencePattern : PyAstSequencePattern, PyPattern {
val elements: List<PyPattern>
val elements: List<PyPattern>
get() = findChildrenByClass(PyPattern::class.java).toList()
}
@@ -22,5 +22,6 @@ import com.jetbrains.python.psi.stubs.PyStarImportElementStub;
/**
* Marks the star in "from foo import *".
*/
public interface PyStarImportElement extends PyAstStarImportElement, PyImplicitImportNameDefiner, StubBasedPsiElement<PyStarImportElementStub> {
public interface PyStarImportElement
extends PyAstStarImportElement, PyImplicitImportNameDefiner, StubBasedPsiElement<PyStarImportElementStub> {
}
@@ -21,5 +21,5 @@ import com.jetbrains.python.ast.PyAstStatement;
* Everything that may be an element of a statement list.
*/
public interface PyStatement extends PyAstStatement, PyElement {
PyStatement[] EMPTY_ARRAY = new PyStatement[0];
PyStatement[] EMPTY_ARRAY = new PyStatement[0];
}
@@ -10,7 +10,7 @@ import java.util.List;
/**
* A string literal expression can consist of a number of implicitly concatenated string literals
* each with its own set of quotes and prefixes. For instance, the following string literal expression
* each with its own set of quotes and prefixes. For instance, the following string literal expression
* in the right hand side of the assignment:
* <p>
* <code><pre>
@@ -27,13 +27,14 @@ import java.util.List;
* decoded value, etc.
*
* @see <a href="https://docs.python.org/3/reference/lexical_analysis.html#string-literal-concatenation">
* https://docs.python.org/3/reference/lexical_analysis.html#string-literal-concatenation</a>
* https://docs.python.org/3/reference/lexical_analysis.html#string-literal-concatenation</a>
* @see #getStringElements()
* @see PyStringElement
* @see PyPlainStringElement
* @see PyFormattedStringElement
*/
public interface PyStringLiteralExpression extends PyAstStringLiteralExpression, PyLiteralExpression, StringLiteralExpression, PsiLanguageInjectionHost {
public interface PyStringLiteralExpression
extends PyAstStringLiteralExpression, PyLiteralExpression, StringLiteralExpression, PsiLanguageInjectionHost {
/**
* Returns a list of implicitly concatenated string elements composing this literal expression.
*/
@@ -6,7 +6,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface PySubscriptionExpression extends PyAstSubscriptionExpression, PyQualifiedExpression, PyCallSiteExpression, PyReferenceOwner {
public interface PySubscriptionExpression
extends PyAstSubscriptionExpression, PyQualifiedExpression, PyCallSiteExpression, PyReferenceOwner {
/**
* @return For {@code spam[x][y][n]} will return {@code spam} regardless number of its dimensions
@@ -11,8 +11,9 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents Type Alias Statement added in <a href="https://peps.python.org/pep-0695/">PEP 695</a>
*/
public interface PyTypeAliasStatement extends PyAstTypeAliasStatement, PyStatement, PsiNameIdentifierOwner, PyTypeParameterListOwner, PyTypedElement,
StubBasedPsiElement<PyTypeAliasStatementStub>, PyQualifiedNameOwner, ScopeOwner {
public interface PyTypeAliasStatement
extends PyAstTypeAliasStatement, PyStatement, PsiNameIdentifierOwner, PyTypeParameterListOwner, PyTypedElement,
StubBasedPsiElement<PyTypeAliasStatementStub>, PyQualifiedNameOwner, ScopeOwner {
@Override
default @Nullable PyExpression getTypeExpression() {
@@ -11,7 +11,8 @@ import org.jetbrains.annotations.Nullable;
* Represents a Type Parameter that can be a part of {@link PyTypeParameterList}<br>
* For more information see <a href="https://peps.python.org/pep-0695/">PEP 695</a>
*/
public interface PyTypeParameter extends PyAstTypeParameter, PyElement, PsiNameIdentifierOwner, PyTypedElement, PyQualifiedNameOwner, StubBasedPsiElement<PyTypeParameterStub> {
public interface PyTypeParameter extends PyAstTypeParameter, PyElement, PsiNameIdentifierOwner, PyTypedElement, PyQualifiedNameOwner,
StubBasedPsiElement<PyTypeParameterStub> {
@Override
default @Nullable PyExpression getBoundExpression() {
@@ -59,6 +59,7 @@ public final class PyPsiUtils {
/**
* Finds first sibling that is neither comment, nor whitespace before given element.
*
* @param strict prohibit returning element itself
*/
public static @Nullable PsiElement getPrevNonCommentSibling(@Nullable PsiElement start, boolean strict) {
@@ -109,6 +110,7 @@ public final class PyPsiUtils {
/**
* Finds first sibling that is neither comment, nor whitespace after given element.
*
* @param strict prohibit returning element itself
*/
public static @Nullable PsiElement getNextNonCommentSibling(@Nullable PsiElement start, boolean strict) {
@@ -117,6 +119,7 @@ public final class PyPsiUtils {
/**
* Finds first token after given element that doesn't consist solely of spaces and is not empty (e.g. error marker).
*
* @param ignoreComments ignore commentaries as well
*/
public static @Nullable PsiElement getNextSignificantLeaf(@Nullable PsiElement element, boolean ignoreComments) {
@@ -128,6 +131,7 @@ public final class PyPsiUtils {
/**
* Finds first token before given element that doesn't consist solely of spaces and is not empty (e.g. error marker).
*
* @param ignoreComments ignore commentaries as well
*/
public static @Nullable PsiElement getPrevSignificantLeaf(@Nullable PsiElement element, boolean ignoreComments) {
@@ -261,7 +265,8 @@ public final class PyPsiUtils {
public static boolean isMethodContext(final PsiElement element) {
final PsiNamedElement parent = PsiTreeUtil.getParentOfType(element, PyFile.class, PyFunction.class, PyClass.class);
// In case if element is inside method which is inside class
if (parent instanceof PyFunction && PsiTreeUtil.getParentOfType(parent, PyFile.class, PyFunction.class, PyClass.class) instanceof PyClass) {
if (parent instanceof PyFunction &&
PsiTreeUtil.getParentOfType(parent, PyFile.class, PyFunction.class, PyClass.class) instanceof PyClass) {
return true;
}
return false;
@@ -302,6 +307,7 @@ public final class PyPsiUtils {
/**
* Returns comments preceding given elements as pair of the first and the last such comments. Comments should not be
* separated by any empty line.
*
* @param element element comments should be adjacent to
* @return described range or {@code null} if there are no such comments
*/
@@ -348,7 +354,7 @@ public final class PyPsiUtils {
* def func():
* pass
* }</pre>
*
* <p>
* Note that in the following case it will additionally return an empty list of comments as the last element
* to distinguish between the cases when there is a blank line above the provided element and when there is not.
*
@@ -32,42 +32,62 @@ import org.jetbrains.annotations.Nullable;
public interface PyQualifiedNameResolveContext {
@Nullable
PsiElement getFoothold();
int getRelativeLevel();
@Nullable
Sdk getSdk();
@Nullable
Module getModule();
@NotNull
Project getProject();
boolean getWithoutRoots();
boolean getWithoutForeign();
boolean getWithoutStubs();
@NotNull
PsiManager getPsiManager();
boolean getWithMembers();
boolean getWithPlainDirectories();
boolean getVisitAllModules();
@Nullable
Sdk getEffectiveSdk();
boolean isValid();
@Nullable
PsiFile getFootholdFile();
@Nullable
PsiDirectory getContainingDirectory();
@NotNull
PyQualifiedNameResolveContext copyWithoutForeign();
@NotNull
PyQualifiedNameResolveContext copyWithMembers();
@NotNull
PyQualifiedNameResolveContext copyWithPlainDirectories();
@NotNull
PyQualifiedNameResolveContext copyWithRelative(int relativeLevel);
@NotNull
PyQualifiedNameResolveContext copyWithoutRoots();
@NotNull
PyQualifiedNameResolveContext copyWithRoots();
@NotNull
PyQualifiedNameResolveContext copyWithoutStubs();
}
@@ -10,6 +10,8 @@ import java.util.List;
public interface PyFileStub extends PsiFileStub<PyFile> {
List<String> getDunderAll();
BitSet getFutureFeatures();
String getDeprecationMessage();
}
@@ -6,9 +6,13 @@ import com.jetbrains.python.psi.PyFunction;
public interface PyFunctionStub extends NamedStub<PyFunction>, PyAnnotationOwnerStub, PyTypeCommentOwnerStub, PyVersionSpecificStub {
String getDocString();
String getDeprecationMessage();
boolean isAsync();
boolean isGenerator();
default boolean onlyRaisesNotImplementedError() {
return false;
}
@@ -2,14 +2,14 @@
package com.jetbrains.python.psi.stubs;
import com.intellij.psi.stubs.StubElement;
import com.jetbrains.python.psi.PyImportElement;
import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.psi.PyImportElement;
import org.jetbrains.annotations.Nullable;
public interface PyImportElementStub extends StubElement<PyImportElement> {
@Nullable
QualifiedName getImportedQName();
String getAsName();
}
@@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable;
public interface PyNamedParameterStub extends NamedStub<PyNamedParameter>, PyAnnotationOwnerStub, PyTypeCommentOwnerStub {
boolean isPositionalContainer();
boolean isKeywordContainer();
default @Nullable String getDefaultValueText() {
@@ -18,7 +18,8 @@ public interface PyCallableParameter {
* Returns null if the parameter is tuple or star, or name is unknown.
*/
@Nullable
@Nls String getName();
@Nls
String getName();
/**
* @param context type evaluation context
@@ -32,6 +32,7 @@ public interface PyClassLikeType extends PyCallableType, PyWithAncestors, PyInst
boolean inherited);
// TODO: Pull to PyType at next iteration
/**
* Visits all class members. This method is better then bare class since it uses type info and supports not only classes but
* class-like structures as well. Consider using user-friendly wrapper {@link PyTypeUtil#getMembersOfType(PyClassLikeType, Class, boolean, TypeEvalContext)}
@@ -39,9 +39,9 @@ public class PyClassMembersProviderBase implements PyClassMembersProvider {
* @return found member or null
*/
public static @Nullable PsiElement resolveMemberByName(@NotNull Collection<? extends PyCustomMember> members,
@NotNull String name,
@NotNull PsiElement context,
@NotNull PyResolveContext resolveContext) {
@NotNull String name,
@NotNull PsiElement context,
@NotNull PyResolveContext resolveContext) {
for (PyCustomMember member : members) {
if (member.getName().equals(name)) {
return member.resolve(context, resolveContext);
@@ -18,8 +18,8 @@ package com.jetbrains.python.psi.types;
import org.jetbrains.annotations.NotNull;
/**
* A type that can describe either particular instantiated instance of a class or a class itself.
*
* A type that can describe either particular instantiated instance of a class or a class itself.
*
* @author Mikhail Golubev
*/
public interface PyInstantiableType<T extends PyInstantiableType<T>> extends PyType {
@@ -27,7 +27,9 @@ public abstract class PyModuleMembersProvider {
* @param context type evaluation context
* @return provided members
*/
public @NotNull Collection<PyCustomMember> getMembers(@NotNull PyFile module, @NotNull PointInImport point, @NotNull TypeEvalContext context) {
public @NotNull Collection<PyCustomMember> getMembers(@NotNull PyFile module,
@NotNull PointInImport point,
@NotNull TypeEvalContext context) {
final VirtualFile vFile = module.getVirtualFile();
if (vFile != null) {
final String qName = PyPsiFacade.getInstance(module.getProject()).findShortestImportableName(vFile, module);
@@ -64,6 +66,6 @@ public abstract class PyModuleMembersProvider {
* @return provided members
*/
protected abstract @NotNull Collection<PyCustomMember> getMembersByQName(@NotNull PyFile module,
@NotNull String qName,
@NotNull TypeEvalContext context);
@NotNull String qName,
@NotNull TypeEvalContext context);
}
@@ -8,7 +8,7 @@ import com.jetbrains.python.psi.PyExpression
import com.jetbrains.python.psi.resolve.PyResolveContext
import com.jetbrains.python.psi.resolve.RatedResolveResult
class PyNeverType private constructor(private val name: String): PyType {
class PyNeverType private constructor(private val name: String) : PyType {
companion object {
@JvmField val NEVER: PyNeverType = PyNeverType("Never")
@JvmField val NO_RETURN: PyNeverType = PyNeverType("NoReturn")
@@ -16,7 +16,7 @@ class PyNeverType private constructor(private val name: String): PyType {
@JvmStatic
fun PyType?.toNoReturnIfNeeded(): PyType? = if (this === NEVER) NO_RETURN else this
}
override fun getName(): String = name
override fun isBuiltin(): Boolean = true
override fun assertValid(message: String?) {}
@@ -30,7 +30,7 @@ class PyNeverType private constructor(private val name: String): PyType {
direction: AccessDirection,
resolveContext: PyResolveContext,
): List<RatedResolveResult> = emptyList()
override fun getCompletionVariants(
completionPrefix: String?,
location: PsiElement?,
@@ -35,7 +35,9 @@ public class PyTypeProviderBase implements PyTypeProvider {
}
@Override
public @Nullable Ref<PyType> getParameterType(@NotNull PyNamedParameter param, @NotNull PyFunction func, @NotNull TypeEvalContext context) {
public @Nullable Ref<PyType> getParameterType(@NotNull PyNamedParameter param,
@NotNull PyFunction func,
@NotNull TypeEvalContext context) {
return null;
}
@@ -45,7 +47,9 @@ public class PyTypeProviderBase implements PyTypeProvider {
}
@Override
public @Nullable Ref<PyType> getCallType(@NotNull PyFunction function, @NotNull PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
public @Nullable Ref<PyType> getCallType(@NotNull PyFunction function,
@NotNull PyCallSiteExpression callSite,
@NotNull TypeEvalContext context) {
final ReturnTypeDescriptor descriptor;
synchronized (myMethodToReturnTypeMap) {
descriptor = myMethodToReturnTypeMap.get(function.getName());
@@ -120,7 +124,9 @@ public class PyTypeProviderBase implements PyTypeProvider {
myStringToReturnTypeMap.put(classQualifiedName, callback);
}
public @Nullable Ref<PyType> get(@NotNull PyFunction function, @Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
public @Nullable Ref<PyType> get(@NotNull PyFunction function,
@Nullable PyCallSiteExpression callSite,
@NotNull TypeEvalContext context) {
return Optional
.ofNullable(function.getContainingClass())
.map(pyClass -> myStringToReturnTypeMap.get(pyClass.getQualifiedName()))
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.Nullable;
* Because the "unknown" type is historically represented as {@code null} in the type system, {@code PyTypeVisitor.visitPyType(type, visitor)}
* should be used instead of direct {@code type.acceptTypeVisitor(visitor)} to properly account for possible {@code null} values.
* <p>
* This class gives access only to the types declared in the <tt>intellij.python.psi</tt> module.
* This class gives access only to the types declared in the <tt>intellij.python.psi</tt> module.
* Most actual implementations should extend {@link PyTypeVisitorExt}.
* <p>
* There are helper {@link PyRecursiveTypeVisitor} and {@link PyCloningTypeVisitor} for recursive type
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nullable;
* @see PyRecursiveTypeVisitor
* @see PyCloningTypeVisitor
* @see PyType#acceptTypeVisitor(PyTypeVisitor)
* @see #visit(PyType, PyTypeVisitor)
* @see #visit(PyType, PyTypeVisitor)
* @see #visitUnknownType()
*/
@ApiStatus.Experimental
@@ -74,7 +74,7 @@ public abstract class PyTypeVisitor<T> {
public T visitPyCallableParameterListType(@NotNull PyCallableParameterListType callableParameterListType) {
return visitPyType(callableParameterListType);
}
public T visitPyNeverType(@NotNull PyNeverType neverType) {
return visitPyType(neverType);
}
@@ -39,7 +39,7 @@ public final class TypeEvalConstraints {
if (this == o) return true;
if (!(o instanceof TypeEvalConstraints that)) return false;
return myAllowDataFlow == that.myAllowDataFlow &&
return myAllowDataFlow == that.myAllowDataFlow &&
myAllowStubToAST == that.myAllowStubToAST &&
myAllowCallContext == that.myAllowCallContext &&
Objects.equals(myOrigin, that.myOrigin);
@@ -268,7 +268,9 @@ public sealed class TypeEvalContext {
myConstraints.myAllowStubToAST,
myConstraints.myAllowCallContext,
// code completion will always have a new PsiFile, use original file instead
myConstraints.myOrigin != null ? myConstraints.myOrigin.getOriginalFile() : null);
myConstraints.myOrigin != null
? myConstraints.myOrigin.getOriginalFile()
: null);
return project.getService(TypeEvalContextCache.class).getLibraryContext(new LibraryTypeEvalContext(constraints));
}
@@ -430,7 +432,7 @@ public sealed class TypeEvalContext {
}
private static class PyNullType implements PyType {
private PyNullType() {}
private PyNullType() { }
@Override
public @Nullable List<? extends RatedResolveResult> resolveMember(@NotNull String name,
@@ -1,8 +1,8 @@
<html>
<body>
<p>
Checks <code>typing.assert_type(val, typ, /)</code> calls and reports cases when <code>val</code>'s inferred type is not
<code>typ</code>.
Checks <code>typing.assert_type(val, typ, /)</code> calls and reports cases when <code>val</code>'s inferred type is not
<code>typ</code>.
</p>
<p><b>Example:</b></p>
<pre><code>
@@ -6,7 +6,8 @@
and <code>typing.cast</code> does not dynamically validate the type.</p>
<p>This check applies even to types that could theoretically have a common descendant.
For example, it will flag a cast between two sibling classes <code>Left</code> and <code>Right</code> that both inherit from <code>Top</code>,
For example, it will flag a cast between two sibling classes <code>Left</code> and <code>Right</code> that both inherit from
<code>Top</code>,
because there is no direct inheritance relationship between them.</p>
<p><b>Example:</b></p>
@@ -14,4 +14,5 @@ class Account:
</code></pre>
<p>As a fix, you might want to check and modify the algorithm to ensure that reassignment is needed. If everything is correct,
you can invoke intention actions for this code and opt to ignore the warning.</p>
</body></html>
</body>
</html>
@@ -1,6 +1,7 @@
<html>
<body>
<p>Reports type errors in function call expressions, targets, and return values. In a dynamically typed language, this is possible in a limited number of cases. </p>
<p>Reports type errors in function call expressions, targets, and return values. In a dynamically typed language, this is possible in a
limited number of cases. </p>
<p>Types of function parameters can be specified in
docstrings or in Python 3 function annotations.</p>
<p><b>Example:</b></p>
@@ -17,6 +17,7 @@ def c(p1, p2): # Type signature has too many arguments
# type: (int) -> int
pass
</code></pre>
<p>Available quick-fixes offer various actions. You can rename, remove, or move problematic elements. You can also manually modify type declarations to ensure no warning is shown.</p>
<p>Available quick-fixes offer various actions. You can rename, remove, or move problematic elements. You can also manually modify type
declarations to ensure no warning is shown.</p>
</body>
</html>
@@ -10,4 +10,5 @@ else:
</code></pre>
<p>As a fix, you might want to check and modify the algorithm to ensure it implements
the expected logic.</p>
</body></html>
</body>
</html>
@@ -3,4 +3,5 @@
<p>
Reports local variables, parameters, and functions that are locally defined, but not used name in a function.
</p>
</body></html>
</body>
</html>
@@ -5,7 +5,8 @@ This intention converts string formatting via <code>format()</code> method and f
</span>
<!-- tooltip end -->
<span>
F-strings provide a way to embed expressions inside string literals, using a minimal syntax. See more details in <a href="https://www.python.org/dev/peps/pep-0498/">PEP-498</a>.
F-strings provide a way to embed expressions inside string literals, using a minimal syntax. See more details in <a
href="https://www.python.org/dev/peps/pep-0498/">PEP-498</a>.
</span>
</body>
</html>
@@ -1,7 +1,8 @@
<html>
<body>
<span>
Converts <a href="https://www.python.org/dev/peps/pep-0484/">PEP-484</a> type comments to Python 3.6 <a href="https://www.python.org/dev/peps/pep-0526/">variable annotations</a>.
Converts <a href="https://www.python.org/dev/peps/pep-0484/">PEP-484</a> type comments to Python 3.6 <a
href="https://www.python.org/dev/peps/pep-0526/">variable annotations</a>.
</span>
</body>
</html>
@@ -116,7 +116,7 @@ public final class PyNewStyleStringFormatParser {
int autoFieldNumber = myImplicitlyNumberedFieldsCounter;
// in the order of appearance inside a field
final IntList attrAndLookupBounds=new IntArrayList();
final IntList attrAndLookupBounds = new IntArrayList();
int conversionStart = -1;
int formatSpecStart = -1;
final List<Field> nestedFields = new ArrayList<>();
@@ -33,7 +33,8 @@ public final class PyPsiBundle extends DynamicBundle {
return INSTANCE.getMessage(key, params);
}
public static @NotNull Supplier<@Nls String> messagePointer(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) {
public static @NotNull Supplier<@Nls String> messagePointer(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key,
Object @NotNull ... params) {
return INSTANCE.getLazyMessage(key, params);
}
}
@@ -38,7 +38,7 @@ object PyPsiPackageUtil {
return buildMap {
try {
val resourceAsStream = requireNotNull(PyPsiPackageUtil::class.java.getClassLoader().getResourceAsStream("tools/packages"))
{ "tool/packages is missed in distribution "}
{ "tool/packages is missed in distribution " }
for (line in ResourceUtil.loadText(resourceAsStream).lines()) {
val split = line.trim().split(" ")
check(split.size == 2) { "Each line should contain exactly two names: $line" }
@@ -289,8 +289,8 @@ public class PyStringFormatParser {
myPos = 0;
while (myPos < myLiteral.length()) {
int next = myLiteral.indexOf('%', myPos);
while(next >= 0 && next < myLiteral.length()-1 && myLiteral.charAt(next+1) == '%') {
next = myLiteral.indexOf('%', next+2);
while (next >= 0 && next < myLiteral.length() - 1 && myLiteral.charAt(next + 1) == '%') {
next = myLiteral.indexOf('%', next + 2);
}
if (next < 0) break;
if (next > myPos) {
@@ -474,7 +474,7 @@ public class PyStringFormatParser {
chunk.setMappingKey(myLiteral.substring(myPos + 1, mappingEnd));
myPos = mappingEnd + 1;
}
else {
else {
chunk.setAutoPosition(mySubstitutionsCount);
mySubstitutionsCount++;
}
@@ -7,7 +7,7 @@ import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
open class PythonDocumentationHighlightingService {
companion object{
companion object {
@JvmStatic
fun getInstance(): PythonDocumentationHighlightingService {
return service()
@@ -75,5 +75,4 @@ public class PythonParserDefinition implements ParserDefinition {
// see LanguageTokenSeparatorGenerator instead
return SpaceRequirements.MAY;
}
}
@@ -52,7 +52,8 @@ public final class PythonTemplateRunner {
if (editor != null) {
Template template = builder.buildInlineTemplate();
TemplateManager.getInstance(project).startTemplate(editor, template);
} else {
}
else {
builder.runNonInteractively(true);
}
}
@@ -25,11 +25,11 @@ import java.util.List;
@ApiStatus.Experimental
public class PythonUiService {
public void showBalloonInfo(Project project, @PopupContent String message) {}
public void showBalloonInfo(Project project, @PopupContent String message) { }
public void showBalloonWarning(Project project, @PopupContent String message) {}
public void showBalloonWarning(Project project, @PopupContent String message) { }
public void showBalloonError(Project project, @PopupContent String message) {}
public void showBalloonError(Project project, @PopupContent String message) { }
public FileEditor getSelectedEditor(@NotNull Project project, VirtualFile virtualFile) {
return null;
@@ -55,7 +55,7 @@ public class PythonUiService {
PsiElement element,
String newName,
boolean searchInComments,
boolean searchTextOccurrences) {}
boolean searchTextOccurrences) { }
public LocalQuickFix createPyChangeSignatureQuickFixForMismatchingMethods(PyFunction function, PyFunction method) {
return null;
@@ -119,6 +119,5 @@ public class PythonUiService {
@ListItem String initialValue,
@Nullable Icon icon) {
return -1;
}
}
@@ -126,7 +126,8 @@ private fun getInvertedConditionExpression(
level: LanguageLevel,
generator: PyElementGenerator,
expression: PyExpression,
isTopLevelExpression: Boolean): PyExpression {
isTopLevelExpression: Boolean,
): PyExpression {
if (expression is PyParenthesizedExpression) {
return getInvertedConditionExpression(
project, file, level, generator, expression.containedExpression!!, isTopLevelExpression)
@@ -271,7 +272,8 @@ private fun requiresParentheses(element: PsiElement): Boolean {
}
private fun createOrExpression(
level: LanguageLevel, generator: PyElementGenerator, expressions: Iterable<PyExpression>, isTopLevelExpression: Boolean): PyExpression {
level: LanguageLevel, generator: PyElementGenerator, expressions: Iterable<PyExpression>, isTopLevelExpression: Boolean,
): PyExpression {
val result = StringBuilder()
val requiresParentheses = !isTopLevelExpression && expressions.count() > 1
@@ -57,5 +57,4 @@ public final class PyDataclassClassMembersProvider extends PyClassMembersProvide
return CachedValueProvider.Result.create(result, PsiModificationTracker.MODIFICATION_COUNT);
});
}
}
@@ -176,7 +176,7 @@ fun resolvesToOmittedDefault(expression: PyExpression, type: Type): Boolean {
val qNames = PyResolveUtil.resolveImportedElementQNameLocally(expression)
return when (type.asPredefinedType) {
PyDataclassParameters.PredefinedType.STD, PyDataclassParameters.PredefinedType.DATACLASS_TRANSFORM ->
PyDataclassParameters.PredefinedType.STD, PyDataclassParameters.PredefinedType.DATACLASS_TRANSFORM ->
qNames.any { it.toString() == PyDataclassNames.Dataclasses.DATACLASSES_MISSING }
PyDataclassParameters.PredefinedType.ATTRS -> qNames.any { it.toString() in PyDataclassNames.Attrs.ATTRS_NOTHING }
else -> false
@@ -245,28 +245,28 @@ private fun parseDataclassParametersFromAST(cls: PyClass, context: TypeEvalConte
for (decorator in decorators.decorators) {
val callee = (decorator.callee as? PyReferenceExpression) ?: continue
for (decoratorQualifiedName in PyResolveUtil.resolveImportedElementQNameLocally(callee)) {
val types = decoratorAndTypeAndMarkedCallee(cls.project)
val decoratorAndTypeAndMarkedCallee = types.firstOrNull { it.first == decoratorQualifiedName } ?: continue
val mapping = decorator.mapArguments(
PyCallableTypeImpl(decoratorAndTypeAndMarkedCallee.third, null),
context ?: TypeEvalContext.codeInsightFallback(cls.project)
)
val builder = PyDataclassParametersBuilder(decoratorAndTypeAndMarkedCallee.second, decoratorAndTypeAndMarkedCallee.first)
mapping
.mappedParameters
.entries
.forEach {
builder.update(it.value.name, it.key)
}
return builder.build()
}
// Process decorators that have dataclass_transform-compatible keyword arguments.
if (decorator.qualifiedName == null) continue
val decoratorKeywordArguments = decorator.arguments.filterIsInstance<PyKeywordArgument>()
@@ -559,10 +559,10 @@ private fun resolveDataclassParameters(
// TODO remove this hack, make it a proper field
val extraArguments = mutableMapOf<String, PyExpression>()
if (type.asPredefinedType == PyDataclassParameters.PredefinedType.ATTRS && stub.decoratorName() == PyKnownDecorator.ATTR_DATACLASS.qualifiedName) {
extraArguments["auto_attribs"] =
extraArguments["auto_attribs"] =
PyElementGenerator.getInstance(pyClass.project).createExpressionFromText(LanguageLevel.forElement(pyClass), PyNames.TRUE)
}
return PyDataclassParameters(
init = stub.initValue() ?: true,
repr = stub.reprValue() ?: true,
@@ -603,8 +603,8 @@ private fun resolveDataclassParameters(
.overStub { dtStub -> dtStub }
.withStubBuilder(PyDataclassTransformDecoratorStub::create)
.compute(context)
if (dataclassTransformStub != null) {
val resolvedFieldSpecifiers = dataclassTransformStub.fieldSpecifiers
.flatMap { PyResolveUtil.resolveQualifiedNameInScope(it, ScopeUtil.getScopeOwner(dataclassTransformDecorator)!!, context) }
@@ -690,7 +690,7 @@ fun resolveDataclassFieldParameters(
context: TypeEvalContext,
): PyDataclassFieldParameters? {
assert(field.containingClass == dataclass)
val assignedQName = field.assignedQName
if (assignedQName != null) {
val resolvesToMissingOrNothing = PyResolveUtil.resolveQualifiedNameInScope(assignedQName, ScopeUtil.getScopeOwner(dataclass)!!, context)
@@ -707,7 +707,7 @@ fun resolveDataclassFieldParameters(
)
}
}
val fieldStub = if (field.stub != null) {
// TODO access the green stub here
field.stub.getCustomStub(PyDataclassFieldStub::class.java)
@@ -729,16 +729,16 @@ fun resolveDataclassFieldParameters(
if (field.calleeName == null) return null
val fieldSpecifierDeclaration = PyResolveUtil.resolveQualifiedNameInScope(field.calleeName!!, ScopeUtil.getScopeOwner(dataclass)!!, context)
.filterIsInstance<PyQualifiedNameOwner>()
.firstOrNull {
.firstOrNull {
val qualifiedName = it.qualifiedName
qualifiedName != null && QualifiedName.fromDottedString(qualifiedName) in dataclassParams.fieldSpecifiers
qualifiedName != null && QualifiedName.fromDottedString(qualifiedName) in dataclassParams.fieldSpecifiers
}
if (fieldSpecifierDeclaration == null) return null
val fieldSpecifierCallable = when (fieldSpecifierDeclaration) {
is PyClass -> fieldSpecifierDeclaration.findInitOrNew(true, context)
is PyFunction -> fieldSpecifierDeclaration
else -> null
}
}
if (fieldSpecifierCallable == null) return null
return PyDataclassFieldParameters(
hasDefault = fieldStub?.hasDefault() ?: false,
@@ -75,7 +75,7 @@ open class PySoftFileReferenceContributor : PsiReferenceContributor() {
parameterNames.any(::matchesPathNamePattern)
}
.any {
val mapping = callExpr.mapArguments( it, typeEvalContext)
val mapping = callExpr.mapArguments(it, typeEvalContext)
val parameterName = mapping.mappedParameters[expr]?.name ?: return@any false
matchesPathNamePattern(parameterName)
}
@@ -110,12 +110,12 @@ open class PySoftFileReferenceContributor : PsiReferenceContributor() {
val mapping = callExpr.mapArguments(it, typeEvalContext)
mapping.mappedParameters[expr]?.getArgumentType(typeEvalContext)
}
// We can't use PyTypeChecker.match directly because the type `str | PathLike` is considered incompatible
// with neither str nor PathLike (strict union semantics).
fun PyType.allowsValuesCompatibleWith(superType: PyType): Boolean =
fun PyType.allowsValuesCompatibleWith(superType: PyType): Boolean =
PyTypeUtil.toStream(this).anyMatch { it != null && PyTypeChecker.match(superType, it, typeEvalContext) }
return argumentTypes.any { it.allowsValuesCompatibleWith(bytesOrUnicodeType) } &&
argumentTypes.any { it.allowsValuesCompatibleWith(osPathLikeType) }
}
@@ -207,9 +207,11 @@ open class PySoftFileReferenceContributor : PsiReferenceContributor() {
override fun createFileReference(range: TextRange, index: Int, text: String): FileReference? =
doCreateFileReference(range, index, expandUserHome(text))
open fun doCreateFileReference(range: TextRange,
index: Int,
expandedText: String?): FileReference? =
open fun doCreateFileReference(
range: TextRange,
index: Int,
expandedText: String?,
): FileReference? =
super.createFileReference(range, index, expandedText)
override fun isAbsolutePathReference(): Boolean =
@@ -104,7 +104,8 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
private @NotNull Ref<PyExpression> resolveKeywordFormat(@NotNull PyArgumentList argumentList) {
final Ref<PyExpression> valueExprRef = getKeyValueFromArguments(argumentList);
final String indexElement = myChunk instanceof NewStyleSubstitutionChunk ? ((NewStyleSubstitutionChunk)myChunk).getMappingKeyElementIndex() : null;
final String indexElement =
myChunk instanceof NewStyleSubstitutionChunk ? ((NewStyleSubstitutionChunk)myChunk).getMappingKeyElementIndex() : null;
if (valueExprRef != null && !valueExprRef.isNull() && indexElement != null) {
final PyExpression valueExpr = PyPsiUtils.flattenParens(valueExprRef.get());
assert valueExpr != null;
@@ -130,7 +131,7 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
if (valueFromKeywordArg != null) {
valueExprRef = Ref.create(valueFromKeywordArg.getValueExpression());
}
else if (!keywordStarArgs.isEmpty()){
else if (!keywordStarArgs.isEmpty()) {
for (PyStarArgument arg : keywordStarArgs) {
final Ref<PyExpression> resolvedRef = resolveKeywordStarExpression(arg);
if (resolvedRef != null && (valueExprRef == null || valueExprRef.get() == null)) {
@@ -256,7 +257,9 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
return null;
}
boolean isKeyWordSubstitution = myChunk.getMappingKey() != null;
return isKeyWordSubstitution ? resolveKeywordPercent(rightExpression, myChunk.getMappingKey()) : resolvePositionalPercent(rightExpression);
return isKeyWordSubstitution
? resolveKeywordPercent(rightExpression, myChunk.getMappingKey())
: resolvePositionalPercent(rightExpression);
}
return null;
}
@@ -297,7 +300,7 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
}
}
else if (myPosition != 0 && PsiTreeUtil.instanceOf(containedExpression, PyLiteralExpression.class, PySetLiteralExpression.class,
PyListLiteralExpression.class, PyDictLiteralExpression.class)) {
PyListLiteralExpression.class, PyDictLiteralExpression.class)) {
return null;
}
return containedExpression;
@@ -347,8 +350,9 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
private @Nullable Ref<PyExpression> resolvePositionalStarExpression(@NotNull PyStarArgument starArgument, int argumentPosition) {
assert myPosition >= 0;
final PyExpression expr = PyPsiUtils.flattenParens(PsiTreeUtil.getChildOfAnyType(starArgument, PyListLiteralExpression.class, PyParenthesizedExpression.class,
PyStringLiteralExpression.class));
final PyExpression expr =
PyPsiUtils.flattenParens(PsiTreeUtil.getChildOfAnyType(starArgument, PyListLiteralExpression.class, PyParenthesizedExpression.class,
PyStringLiteralExpression.class));
if (expr == null) {
return Ref.create(starArgument);
}
@@ -374,7 +378,10 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
return resolveDoubleStar(expression, mappingKey, false, allKeysForSure);
}
private @Nullable Ref<PyExpression> resolveDoubleStar(@NotNull PyDictLiteralExpression expression, @NotNull String mappingKey, boolean isNumeric, boolean allKeysForSure) {
private @Nullable Ref<PyExpression> resolveDoubleStar(@NotNull PyDictLiteralExpression expression,
@NotNull String mappingKey,
boolean isNumeric,
boolean allKeysForSure) {
final LanguageLevel languageLevel = LanguageLevel.forElement(expression);
PyDoubleStarExpression[] starExpressions = PsiTreeUtil.getChildrenOfType(expression, PyDoubleStarExpression.class);
if (languageLevel.isAtLeast(LanguageLevel.PYTHON35) && starExpressions != null) {
@@ -391,7 +398,7 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
}
allKeysForSure = element != null;
if (element != null && !element.isNull()) return element;
if (element != null && !element.isNull()) return element;
}
else if (underStarExpr instanceof PyCallExpression) {
Ref<PyExpression> element = resolveDictCall((PyCallExpression)underStarExpr, mappingKey, true);
@@ -31,11 +31,11 @@ public final class PyClassInsertHandler implements InsertHandler<LookupElement>
PyClass pyClass = PyUtil.as(item.getPsiElement(), PyClass.class);
PyFunction init = pyClass != null ? pyClass.findInitOrNew(true, null) : null;
if (init != null && PyFunctionInsertHandler.hasParams(context, init)) {
editor.getCaretModel().moveToOffset(offset+1);
editor.getCaretModel().moveToOffset(offset + 1);
AutoPopupController.getInstance(context.getProject()).autoPopupParameterInfo(context.getEditor(), init);
}
else {
editor.getCaretModel().moveToOffset(offset+2);
editor.getCaretModel().moveToOffset(offset + 2);
}
}
}
@@ -100,7 +100,7 @@ class PyClassNameCompletionContributor : CompletionContributor(), DumbAware {
return
}
}
val project = originalFile.getProject()
val typeEvalContext = TypeEvalContext.codeCompletion(project, originalFile)
val maxVariants = intValue("ide.completion.variant.limit")
@@ -109,7 +109,7 @@ class PyClassNameCompletionContributor : CompletionContributor(), DumbAware {
val fileBasedIndex = FileBasedIndex.getInstance()
TimeoutUtil.run<RuntimeException>(ThrowableRunnable {
val alreadySuggested: MutableSet<QualifiedName> = HashSet()
// Suggest importable modules and packages
val modulePackageScope = createScope(originalFile, false)
forEachModulePackageNameFromIndex(modulePackageScope) { modulePackageName: String ->
@@ -209,7 +209,7 @@ class PyClassNameCompletionContributor : CompletionContributor(), DumbAware {
private fun getInsertHandler(
exported: PyElement,
position: PsiElement,
typeEvalContext: TypeEvalContext
typeEvalContext: TypeEvalContext,
): InsertHandler<LookupElement> {
if (position.getParent() is PyStringLiteralExpression) {
if (isInsideAllInInitPy(position)) {
@@ -228,7 +228,7 @@ class PyClassNameCompletionContributor : CompletionContributor(), DumbAware {
private fun containsOnlyElementUnderTheCaret(
remainingResults: MutableSet<CompletionResult>,
parameters: CompletionParameters
parameters: CompletionParameters,
): Boolean {
val position = parameters.originalPosition
if (remainingResults.size == 1 && position != null) {
@@ -272,9 +272,9 @@ class PyClassNameCompletionContributor : CompletionContributor(), DumbAware {
private fun isApplicableInInsertionContext(
definition: PyElement,
fqn: QualifiedName,
fqn: QualifiedName,
position: PsiElement,
context: TypeEvalContext
context: TypeEvalContext,
): Boolean {
if (PyTypingTypeProvider.isInsideTypeHint(position, context)) {
// Not all names from typing.py are defined as classes
@@ -295,15 +295,15 @@ class PyClassNameCompletionContributor : CompletionContributor(), DumbAware {
}
return element is PyTypeAliasStatement
}
private fun isInsideErrorElement(referenceExpression: PyReferenceExpression): Boolean {
return referenceExpression.findParentOfType<PsiErrorElement>() != null
}
private fun isInsideImportElement(referenceExpression: PyReferenceExpression): Boolean {
return referenceExpression.findParentOfType<PyImportStatementBase>() != null
}
}
private fun isDirectlyInsideClassBody(referenceExpression: PyReferenceExpression): Boolean {
return referenceExpression.parent is PyExpressionStatement &&
ScopeUtil.getScopeOwner(referenceExpression.parent) is PyClass
@@ -403,7 +403,7 @@ class PyClassNameCompletionContributor : CompletionContributor(), DumbAware {
// See PY-73964, IJPL-265
private const val RECURSIVE_INDEX_ACCESS_ALLOWED = false
}
object InsertHandlers {
internal val importingInsertHandler: InsertHandler<LookupElement> = InsertHandler { context, item ->
addImportForLookupElement(context, item, context.tailOffset - 1)
@@ -445,7 +445,7 @@ class PyClassNameCompletionContributor : CompletionContributor(), DumbAware {
context.document.insertString(context.startOffset, qualifiedNamePrefix)
}
}
fun addImportForLookupElement(context: InsertionContext, item: LookupElement, tailOffset: Int) {
val manager = PsiDocumentManager.getInstance(context.project)
val document = manager.getDocument(context.file)
@@ -60,12 +60,14 @@ fun CompletionParameters.getTypeEvalContext(): TypeEvalContext = TypeEvalContext
* @param pyClass if provided will check if method does not exist already
* @param builderPostprocessor function to be used to tune lookup builder
*/
fun addMethodToResult(result: CompletionResultSet,
pyClass: PyClass?,
typeEvalContext: TypeEvalContext,
methodName: String,
methodParentheses: String = "(self)",
builderPostprocessor: ((LookupElementBuilder) -> LookupElementBuilder)? = null) {
fun addMethodToResult(
result: CompletionResultSet,
pyClass: PyClass?,
typeEvalContext: TypeEvalContext,
methodName: String,
methodParentheses: String = "(self)",
builderPostprocessor: ((LookupElementBuilder) -> LookupElementBuilder)? = null,
) {
if (pyClass?.findMethodByName(methodName, false, typeEvalContext) != null) return
val item = LookupElementBuilder.create(methodName + methodParentheses).withIcon(
@@ -79,11 +81,13 @@ fun addMethodToResult(result: CompletionResultSet,
* @param pyFile if provided will check if function does not exist already
* @param builderPostprocessor function to be used to tune lookup builder
*/
fun addFunctionToResult(result: CompletionResultSet,
pyFile: PyFile?,
functionName: String,
functionParentheses: String = "()",
builderPostprocessor: ((LookupElementBuilder) -> LookupElementBuilder)? = null) {
fun addFunctionToResult(
result: CompletionResultSet,
pyFile: PyFile?,
functionName: String,
functionParentheses: String = "()",
builderPostprocessor: ((LookupElementBuilder) -> LookupElementBuilder)? = null,
) {
if (pyFile?.findTopLevelFunction(functionName) != null) return
val item = LookupElementBuilder.create(functionName + functionParentheses).withIcon(
@@ -126,7 +130,13 @@ const val FALLBACK_WEIGHT = -1_000_000
* @param completionLocation file, in which the completion is taking place
* @param nameOnly indicates that we just need to check the name for underscores
*/
fun computeCompletionWeight(element: PsiElement, elementName: String?, path: QualifiedName?, completionLocation: PsiFile?, nameOnly: Boolean): Int {
fun computeCompletionWeight(
element: PsiElement,
elementName: String?,
path: QualifiedName?,
completionLocation: PsiFile?,
nameOnly: Boolean,
): Int {
var weight = 0
val name = elementName ?: return FALLBACK_WEIGHT
@@ -156,18 +166,18 @@ fun computeCompletionWeight(element: PsiElement, elementName: String?, path: Qua
weight -= LOCATION_NOT_YET_IMPORTED
}
val privatePathComponents = importPath.components.count{ it.startsWith("_") } * PRIVATE_API
val privatePathComponents = importPath.components.count { it.startsWith("_") } * PRIVATE_API
weight -= privatePathComponents + importPath.componentCount
if (vFile != null) {
weight -= when {
weight -= when {
PySkeletonUtil.isStdLib(vFile, sdk) -> LOCATION
ModuleUtilCore.findModuleForFile(vFile, element.project) == null -> LOCATION * 2
else -> 0
}
}
weight -= when(PyUtil.turnInitIntoDir(element)) {
weight -= when (PyUtil.turnInitIntoDir(element)) {
is PsiDirectory -> ELEMENT_TYPE * 2
is PyFile -> ELEMENT_TYPE
else -> 0
@@ -45,9 +45,11 @@ private class DictLiteralCompletionProvider : CompletionProvider<CompletionParam
}
}
private fun addCompletionToCallExpression(originalElement: PsiElement,
possibleSequenceExpr: PySequenceExpression,
result: CompletionResultSet) {
private fun addCompletionToCallExpression(
originalElement: PsiElement,
possibleSequenceExpr: PySequenceExpression,
result: CompletionResultSet,
) {
val typeEvalContext = TypeEvalContext.codeCompletion(originalElement.project, originalElement.containingFile)
val quote = getForcedQuote(possibleSequenceExpr, originalElement)
possibleSequenceExpr.getMappedParameters(PyResolveContext.defaultContext(typeEvalContext))?.forEach {
@@ -67,9 +69,11 @@ private class DictLiteralCompletionProvider : CompletionProvider<CompletionParam
return ""
}
private fun addCompletionToAssignment(originalElement: PsiElement,
possibleSequenceExpr: PySequenceExpression,
result: CompletionResultSet) {
private fun addCompletionToAssignment(
originalElement: PsiElement,
possibleSequenceExpr: PySequenceExpression,
result: CompletionResultSet,
) {
val assignment = PsiTreeUtil.getParentOfType(originalElement, PyAssignmentStatement::class.java)
if (assignment != null) {
val typeEvalContext = TypeEvalContext.codeCompletion(originalElement.project, originalElement.containingFile)
@@ -97,9 +101,11 @@ private class DictLiteralCompletionProvider : CompletionProvider<CompletionParam
}
}
private fun addCompletionToReturnStatement(originalElement: PsiElement,
possibleSequenceExpr: PySequenceExpression,
result: CompletionResultSet) {
private fun addCompletionToReturnStatement(
originalElement: PsiElement,
possibleSequenceExpr: PySequenceExpression,
result: CompletionResultSet,
) {
val returnStatement = PsiTreeUtil.getParentOfType(originalElement, PyReturnStatement::class.java)
if (returnStatement != null) {
val typeEvalContext = TypeEvalContext.codeCompletion(originalElement.project, originalElement.containingFile)
@@ -115,10 +121,12 @@ private class DictLiteralCompletionProvider : CompletionProvider<CompletionParam
}
}
private fun addCompletionForTypedDictKeys(expectedType: PyType?,
expression: PyExpression,
dictCompletion: CompletionResultSet,
quote: String) {
private fun addCompletionForTypedDictKeys(
expectedType: PyType?,
expression: PyExpression,
dictCompletion: CompletionResultSet,
quote: String,
) {
if (expectedType is PyTypedDictType) {
val keys = when (expression) {
is PyDictLiteralExpression -> expression.elements
@@ -116,7 +116,7 @@ public final class PyDocstringCompletionContributor extends CompletionContributo
}
final String text = file.getText();
StringBuilder prefixBuilder = new StringBuilder();
while(offset > 0 && Character.isLetterOrDigit(text.charAt(offset))) {
while (offset > 0 && Character.isLetterOrDigit(text.charAt(offset))) {
prefixBuilder.insert(0, text.charAt(offset));
offset--;
}
@@ -77,7 +77,9 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
PsiElement prev = p.getPrevSibling();
while (prev instanceof PsiWhiteSpace) prev = prev.getPrevSibling();
if (prev == null) return true; // there was only whitespace before us
if (prev instanceof PyStatement || prev instanceof PsiComment || prev instanceof OuterLanguageElement) { // a non-stmt would be something strange
if (prev instanceof PyStatement ||
prev instanceof PsiComment ||
prev instanceof OuterLanguageElement) { // a non-stmt would be something strange
if (prev.getLastChild() instanceof PsiErrorElement) {
// prev stmt ends with an error. are we on the same line?
PsiDocumentManager docMgr = PsiDocumentManager.getInstance(p.getProject());
@@ -240,8 +242,9 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
psiElement().inFile(psiFile(PyDocstringFile.class)));
private static final ElementPattern<PsiElement> IN_FUNCTION_HEADER =
psiElement().inside(PyFunction.class).andNot(or(psiElement().inside(false, psiElement(PyStatementList.class), psiElement(PyFunction.class)),
psiElement().inside(false, psiElement(PyParameterList.class), psiElement(PyFunction.class))));
psiElement().inside(PyFunction.class)
.andNot(or(psiElement().inside(false, psiElement(PyStatementList.class), psiElement(PyFunction.class)),
psiElement().inside(false, psiElement(PyParameterList.class), psiElement(PyFunction.class))));
public static final PsiElementPattern.Capture<PsiElement> AFTER_QUALIFIER =
psiElement().afterLeaf(psiElement().withText(".").inside(PyReferenceExpression.class));
@@ -307,7 +310,8 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private static final PsiElementPattern.Capture<PsiElement> IN_PARAM_LIST = psiElement().inside(PyParameterList.class);
private static final PsiElementPattern.Capture<PsiElement> IN_ARG_LIST = psiElement().inside(PyArgumentList.class);
private static final PsiElementPattern.Capture<PsiElement> IN_DECORATOR_ARG_LIST = psiElement().inside(PyArgumentList.class).inside(PyDecorator.class);
private static final PsiElementPattern.Capture<PsiElement> IN_DECORATOR_ARG_LIST =
psiElement().inside(PyArgumentList.class).inside(PyDecorator.class);
private static final PsiElementPattern.Capture<PsiElement> IN_DEF_BODY =
psiElement().inside(false, psiElement(PyFunction.class), psiElement(PyClass.class));
@@ -338,7 +342,7 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private static final PsiElementPattern.Capture<PsiElement> AFTER_COND_STMT_NO_ELSE =
afterStatement(psiElement().withChild(psiElement(PyConditionalStatementPart.class))
.withLastChild(not(psiElement(PyElsePart.class))));
.withLastChild(not(psiElement(PyElsePart.class))));
private static <T extends PsiElement> PsiElementPattern.Capture<PsiElement> afterStatement(final PsiElementPattern.Capture<T> statementPattern) {
return psiElement().atStartOf(psiElement(PyExpressionStatement.class)
@@ -372,7 +376,8 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
));
*/
private static final FilterPattern PY3K = new FilterPattern(new PyKeywordCompletionContributor.LanguageLevelAtLeastFilter(LanguageLevel.PYTHON30));
private static final FilterPattern PY3K =
new FilterPattern(new PyKeywordCompletionContributor.LanguageLevelAtLeastFilter(LanguageLevel.PYTHON30));
private static final FilterPattern PY35 = new FilterPattern(new LanguageLevelAtLeastFilter(LanguageLevel.PYTHON35));
private static final FilterPattern PY310 = new FilterPattern(new LanguageLevelAtLeastFilter(LanguageLevel.PYTHON310));
@@ -458,7 +463,8 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
final @NotNull ProcessingContext context,
final @NotNull CompletionResultSet result
) {
putKeywords(result, TailTypes.spaceType(), PyNames.ASSERT, PyNames.DEL, PyNames.EXEC, PyNames.FROM, PyNames.IMPORT, PyNames.RAISE);
putKeywords(result, TailTypes.spaceType(), PyNames.ASSERT, PyNames.DEL, PyNames.EXEC, PyNames.FROM, PyNames.IMPORT,
PyNames.RAISE);
putKeywords(result, TailTypes.noneType(), PyNames.PASS);
}
}
@@ -470,12 +476,12 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addBreak() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(IN_BEGIN_STMT)
.andNot(AFTER_QUALIFIER)
.andNot(IN_PARAM_LIST)
.andNot(IN_ARG_LIST)
.and(IN_LOOP)
.withLanguage(PythonLanguage.getInstance())
.and(IN_BEGIN_STMT)
.andNot(AFTER_QUALIFIER)
.andNot(IN_PARAM_LIST)
.andNot(IN_ARG_LIST)
.and(IN_LOOP)
,
new PyKeywordCompletionProvider(TailTypes.noneType(), PyNames.BREAK)
);
@@ -484,13 +490,13 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addContinue() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(IN_BEGIN_STMT)
.andNot(AFTER_QUALIFIER)
.andNot(IN_PARAM_LIST)
.andNot(IN_ARG_LIST)
.andOr(not(IN_FINALLY_NO_LOOP), new FilterPattern(new LanguageLevelAtLeastFilter(LanguageLevel.PYTHON38)))
.and(IN_LOOP)
.withLanguage(PythonLanguage.getInstance())
.and(IN_BEGIN_STMT)
.andNot(AFTER_QUALIFIER)
.andNot(IN_PARAM_LIST)
.andNot(IN_ARG_LIST)
.andOr(not(IN_FINALLY_NO_LOOP), new FilterPattern(new LanguageLevelAtLeastFilter(LanguageLevel.PYTHON38)))
.and(IN_LOOP)
,
new PyKeywordCompletionProvider(TailTypes.noneType(), PyNames.CONTINUE)
);
@@ -509,21 +515,21 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addWithinFuncs() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(IN_DEF_BODY)
.and(IN_BEGIN_STMT)
.andNot(AFTER_QUALIFIER)
.withLanguage(PythonLanguage.getInstance())
.and(IN_DEF_BODY)
.and(IN_BEGIN_STMT)
.andNot(AFTER_QUALIFIER)
,
new PyKeywordCompletionProvider(PyNames.GLOBAL, PyNames.RETURN, PyNames.YIELD)
);
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(IN_DEF_BODY)
.and(IN_BEGIN_STMT)
.and(PY3K)
.andNot(AFTER_QUALIFIER)
.withLanguage(PythonLanguage.getInstance())
.and(IN_DEF_BODY)
.and(IN_BEGIN_STMT)
.and(PY3K)
.andNot(AFTER_QUALIFIER)
,
new PyKeywordCompletionProvider(PyNames.NONLOCAL)
);
@@ -554,10 +560,10 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addWithinIf() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_IF_BODY, AFTER_IF)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_IF_BODY, AFTER_IF)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
,
new PyKeywordCompletionProvider(TailTypes.noneType(), PyUnindentingInsertHandler.INSTANCE, PyNames.ELIF));
}
@@ -565,12 +571,12 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addWithinTry() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_TRY_BODY, IN_EXCEPT_BODY, AFTER_TRY, IN_ELSE_BODY_OF_TRY)
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_TRY_BODY, IN_EXCEPT_BODY, AFTER_TRY, IN_ELSE_BODY_OF_TRY)
//.andNot(RIGHT_AFTER_COLON)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
.andNot(AFTER_FINALLY)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
.andNot(AFTER_FINALLY)
,
new CompletionProvider<>() {
@Override
@@ -585,12 +591,12 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
);
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_TRY_BODY, IN_EXCEPT_BODY, AFTER_TRY, IN_ELSE_BODY_OF_TRY)
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_TRY_BODY, IN_EXCEPT_BODY, AFTER_TRY, IN_ELSE_BODY_OF_TRY)
//.andNot(RIGHT_AFTER_COLON)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
.andNot(AFTER_FINALLY).andNot(AFTER_ELSE)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
.andNot(AFTER_FINALLY).andNot(AFTER_ELSE)
,
new CompletionProvider<>() {
@Override
@@ -608,10 +614,10 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addElse() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_COND_STMT, IN_EXCEPT_BODY, AFTER_COND_STMT_NO_ELSE, AFTER_LOOP_NO_ELSE, AFTER_EXCEPT)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
.withLanguage(PythonLanguage.getInstance())
.and(FIRST_ON_LINE)
.andOr(IN_COND_STMT, IN_EXCEPT_BODY, AFTER_COND_STMT_NO_ELSE, AFTER_LOOP_NO_ELSE, AFTER_EXCEPT)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
,
new PyKeywordCompletionProvider(TailTypes.caseColonType(), PyUnindentingInsertHandler.INSTANCE, PyNames.ELSE));
}
@@ -619,12 +625,12 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addInfixOperators() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.andNot(IN_COMMENT)
.andNot(BEFORE_COND)
.andNot(IN_IMPORT_STMT) // expressions there are not logical anyway
.andNot(IN_PARAM_LIST)
.andNot(AFTER_QUALIFIER).
.withLanguage(PythonLanguage.getInstance())
.andNot(IN_COMMENT)
.andNot(BEFORE_COND)
.andNot(IN_IMPORT_STMT) // expressions there are not logical anyway
.andNot(IN_PARAM_LIST)
.andNot(AFTER_QUALIFIER).
andNot(IN_STRING_LITERAL).and(IN_BEGIN_STMT)
,
new PyKeywordCompletionProvider(PyNames.AND, PyNames.OR, PyNames.IS, PyNames.IN)
@@ -634,14 +640,14 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addNot() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.andNot(IN_COMMENT)
.andNot(IN_IMPORT_STMT)
.andNot(IN_PARAM_LIST)
.andNot(IN_FUNCTION_HEADER)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL).andNot(TARGET_AFTER_QUALIFIER)
.andNot(IN_PATTERN)
.withLanguage(PythonLanguage.getInstance())
.andNot(IN_COMMENT)
.andNot(IN_IMPORT_STMT)
.andNot(IN_PARAM_LIST)
.andNot(IN_FUNCTION_HEADER)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL).andNot(TARGET_AFTER_QUALIFIER)
.andNot(IN_PATTERN)
,
new PyKeywordCompletionProvider(PyNames.NOT, PyNames.LAMBDA)
);
@@ -651,24 +657,24 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
// Add literals in normal contexts
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.andNot(IN_COMMENT)
.andNot(IN_IMPORT_STMT)
.and(NOT_PARAMETER_OR_DEFAULT_VALUE)
.andNot(AFTER_QUALIFIER)
.andNot(IN_FUNCTION_HEADER)
.andNot(IN_STRING_LITERAL)
.andNot(TARGET_AFTER_QUALIFIER)
.withLanguage(PythonLanguage.getInstance())
.andNot(IN_COMMENT)
.andNot(IN_IMPORT_STMT)
.and(NOT_PARAMETER_OR_DEFAULT_VALUE)
.andNot(AFTER_QUALIFIER)
.andNot(IN_FUNCTION_HEADER)
.andNot(IN_STRING_LITERAL)
.andNot(TARGET_AFTER_QUALIFIER)
,
new PyKeywordCompletionProvider(TailTypes.noneType(), PyNames.TRUE, PyNames.FALSE, PyNames.NONE));
// Add literals specifically in decorator argument lists
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(IN_DECORATOR_ARG_LIST)
.andNot(IN_COMMENT)
.andNot(IN_STRING_LITERAL)
.withLanguage(PythonLanguage.getInstance())
.and(IN_DECORATOR_ARG_LIST)
.andNot(IN_COMMENT)
.andNot(IN_STRING_LITERAL)
,
new PyKeywordCompletionProvider(TailTypes.noneType(), PyNames.TRUE, PyNames.FALSE, PyNames.NONE));
extend(CompletionType.BASIC,
@@ -714,10 +720,10 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addAs() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.andOr(IN_IMPORT_AFTER_REF, IN_WITH_AFTER_REF, IN_EXCEPT_AFTER_REF)
.andNot(AFTER_QUALIFIER)
.andNot(IN_COMMENT)
.withLanguage(PythonLanguage.getInstance())
.andOr(IN_IMPORT_AFTER_REF, IN_WITH_AFTER_REF, IN_EXCEPT_AFTER_REF)
.andNot(AFTER_QUALIFIER)
.andNot(IN_COMMENT)
,
new PyKeywordCompletionProvider(PyNames.AS)
);
@@ -726,9 +732,9 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addImportInFrom() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(IN_FROM_IMPORT_AFTER_REF)
.andNot(AFTER_QUALIFIER)
.withLanguage(PythonLanguage.getInstance())
.and(IN_FROM_IMPORT_AFTER_REF)
.andNot(AFTER_QUALIFIER)
,
new PyKeywordCompletionProvider(PyNames.IMPORT)
);
@@ -763,10 +769,10 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addExprElse() {
extend(
CompletionType.BASIC, psiElement()
.withLanguage(PythonLanguage.getInstance())
.afterLeafSkipping(psiElement().whitespace(),
psiElement().inside(psiElement(PyConditionalExpression.class))
.and(psiElement().afterLeaf(PyNames.IF)))
.withLanguage(PythonLanguage.getInstance())
.afterLeafSkipping(psiElement().whitespace(),
psiElement().inside(psiElement(PyConditionalExpression.class))
.and(psiElement().afterLeaf(PyNames.IF)))
,
new PyKeywordCompletionProvider(TailTypes.spaceType(), PyNames.ELSE));
}
@@ -792,8 +798,8 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
.afterLeaf(psiElement().withElementType(PyTokenTypes.AUG_ASSIGN_OPERATIONS)),
psiElement()
.inside(true, psiElement(PyParenthesizedExpression.class)))
.andNot(IN_STRING_LITERAL)
.andNot(IN_COMMENT),
.andNot(IN_STRING_LITERAL)
.andNot(IN_COMMENT),
new PyKeywordCompletionProvider(PyNames.YIELD));
}
@@ -834,11 +840,11 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
private void addForToComprehensions() {
extend(CompletionType.BASIC,
psiElement()
.withLanguage(PythonLanguage.getInstance())
.inside(psiElement(PySequenceExpression.class))
.andNot(psiElement()
.afterLeaf(or(psiElement(PyTokenTypes.LBRACE), psiElement(PyTokenTypes.LBRACKET), psiElement(PyTokenTypes.LPAR))))
.andNot(IN_COMMENT),
.withLanguage(PythonLanguage.getInstance())
.inside(psiElement(PySequenceExpression.class))
.andNot(psiElement()
.afterLeaf(or(psiElement(PyTokenTypes.LBRACE), psiElement(PyTokenTypes.LBRACKET), psiElement(PyTokenTypes.LPAR))))
.andNot(IN_COMMENT),
new PyKeywordCompletionProvider(PyNames.FOR));
}
@@ -848,7 +854,6 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
.withLanguage(PythonLanguage.getInstance())
.and(psiElement()).afterLeaf(psiElement().afterLeaf(PyNames.FOR)),
new PyKeywordCompletionProvider(PyNames.IN));
}
private static final class PyKeywordCompletionProvider extends CompletionProvider<CompletionParameters> {
@@ -47,10 +47,10 @@ public final class PyMetaClassCompletionContributor extends CompletionContributo
});
extend(CompletionType.BASIC,
PlatformPatterns
.psiElement()
.withLanguage(PythonLanguage.getInstance())
.withParents(PyReferenceExpression.class, PyArgumentList.class, PyClass.class)
.and(hasLanguageLevel(level -> !level.isPython2())),
.psiElement()
.withLanguage(PythonLanguage.getInstance())
.withParents(PyReferenceExpression.class, PyArgumentList.class, PyClass.class)
.and(hasLanguageLevel(level -> !level.isPython2())),
new CompletionProvider<>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
@@ -21,7 +21,7 @@ import com.jetbrains.python.psi.impl.PyPsiUtils
import com.jetbrains.python.psi.resolve.PyResolveContext
import com.jetbrains.python.psi.types.PyCallableParameter
class PyMultipleArgumentsCompletionContributor: CompletionContributor(), DumbAware {
class PyMultipleArgumentsCompletionContributor : CompletionContributor(), DumbAware {
init {
extend(CompletionType.BASIC, PlatformPatterns.psiElement().inArgumentList(), MyCompletionProvider)
}
@@ -45,8 +45,9 @@ class PyMultipleArgumentsCompletionContributor: CompletionContributor(), DumbAwa
val argumentIndex = callableType.implicitOffset + argumentExplicitIndex
if (callableParameters == null ||
argumentIndex >= callableParameters.size ||
callableParameters.any { it.isKeywordContainer || it.isPositionalContainer }) {
return@forEach
callableParameters.any { it.isKeywordContainer || it.isPositionalContainer }
) {
return@forEach
}
val unfilledParameters = ContainerUtil.subList(callableParameters, argumentIndex)
@@ -110,7 +111,7 @@ class PyMultipleArgumentsCompletionContributor: CompletionContributor(), DumbAwa
ControlFlowCache.getScope(scope).namedElements
.asSequence()
.filter { element ->
PsiTreeUtil.getParentOfType(element, PyListCompExpression::class.java) ?.let { listComp ->
PsiTreeUtil.getParentOfType(element, PyListCompExpression::class.java)?.let { listComp ->
PsiTreeUtil.isAncestor(listComp.resultExpression, position, false)
} ?: PyPsiUtils.isBefore(element, position)
}
@@ -119,7 +120,7 @@ class PyMultipleArgumentsCompletionContributor: CompletionContributor(), DumbAwa
}
}
class PyMultipleArgumentsInsertHandler(private val call: PyCallExpression): ParenthesesInsertHandler<LookupElement>() {
class PyMultipleArgumentsInsertHandler(private val call: PyCallExpression) : ParenthesesInsertHandler<LookupElement>() {
override fun placeCaretInsideParentheses(context: InsertionContext?, item: LookupElement?): Boolean = false
override fun handleInsert(context: InsertionContext, item: LookupElement) {
@@ -298,7 +298,7 @@ public final class PyStringFormatCompletionContributor extends CompletionContrib
private static @NotNull List<LookupElement> getElementsFromDict(final @NotNull PyDictLiteralExpression dict) {
return Arrays.stream(dict.getElements())
.map(e -> PyUtil.as(e.getKey(), PyStringLiteralExpression.class))
.filter(k-> k != null)
.filter(k -> k != null)
.map(k -> createLookUpElement(k.getStringValue()))
.collect(Collectors.toList());
}
@@ -317,7 +317,7 @@ public final class PyStringFormatCompletionContributor extends CompletionContrib
private static @Nullable LookupElement getKeywordArgument(final @NotNull PyKeywordArgument arg) {
final String keyword = arg.getKeyword();
return keyword != null ? createLookUpElement(keyword) : null;
return keyword != null ? createLookUpElement(keyword) : null;
}
}
@@ -146,8 +146,8 @@ public final class PyStructuralTypeAttributesCompletionContributor extends Compl
* intermediate results in case of a large class hierarchy.
*/
private static @NotNull Set<PyClass> getAncestorClassesFast(@NotNull PyClass pyClass,
@NotNull TypeEvalContext context,
@NotNull Map<PyClass, Set<PyClass>> ancestorsCache) {
@NotNull TypeEvalContext context,
@NotNull Map<PyClass, Set<PyClass>> ancestorsCache) {
final Set<PyClass> ancestors = ancestorsCache.get(pyClass);
if (ancestors != null) {
return ancestors;
@@ -145,7 +145,7 @@ class PyUnresolvedModuleAttributeCompletionContributor : CompletionContributor()
.filterIsInstance<PyFile>()
.map { PyModuleType(it) }
.flatMap { it.getCompletionVariantsAsLookupElements(parameters.position, context, false, false, typeContext) }
.filter { PyNames.isIdentifier(it.lookupString) && !it.lookupString.startsWith('_')}
.filter { PyNames.isIdentifier(it.lookupString) && !it.lookupString.startsWith('_') }
.filter { attribute.isEmpty() || resultMatchingCompleteReference.prefixMatcher.prefixMatches("$qualifier.${it.lookupString}") }
.mapNotNull {
val element = it.psiElement as? PyElement
@@ -15,7 +15,7 @@ import javax.swing.*;
/**
* TODO: Add description
*/
public class PythonLookupElement extends LookupElement implements Comparable<LookupElement>{
public class PythonLookupElement extends LookupElement implements Comparable<LookupElement> {
protected final String myLookupString;
protected final String myTypeText;
@@ -100,6 +100,5 @@ public class PythonLookupElement extends LookupElement implements Comparable<Loo
public int compareTo(final LookupElement o) {
return myLookupString.compareTo(o.getLookupString());
}
}
@@ -27,7 +27,8 @@ import static com.intellij.reference.SoftReference.dereference;
public final class ControlFlowCache {
private static final Key<SoftReference<PyControlFlow>> CONTROL_FLOW_KEY = Key.create("com.jetbrains.python.codeInsight.controlflow.ControlFlow");
private static final Key<SoftReference<PyControlFlow>> CONTROL_FLOW_KEY =
Key.create("com.jetbrains.python.codeInsight.controlflow.ControlFlow");
private static final Key<SoftReference<Scope>> SCOPE_KEY = Key.create("com.jetbrains.python.codeInsight.controlflow.Scope");
private ControlFlowCache() {
@@ -45,11 +45,12 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
private final ControlFlowBuilder myBuilder = new ControlFlowBuilder();
private @Nullable TrueFalseNodes myTrueFalseNodes;
// see com.jetbrains.python.PyPatternTypeTest.testMatchClassPatternShadowingCapture
private final @NotNull List<String> myPatternBindingNames = new ArrayList<>();
private record TrueFalseNodes(@NotNull Instruction trueNode, @NotNull Instruction falseNode) {}
private record TrueFalseNodes(@NotNull Instruction trueNode, @NotNull Instruction falseNode) {
}
public PyControlFlow buildControlFlow(final @NotNull ScopeOwner owner) {
return new PyControlFlow(myBuilder.build(this, owner));
@@ -346,15 +347,15 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
for (PyCaseClause clause : matchStatement.getCaseClauses()) {
myBuilder.prevInstruction = nextClause;
nextClause = addTransparentInstruction();
myPatternBindingNames.clear();
PyPattern pattern = clause.getPattern();
if (pattern != null) {
pattern.accept(this);
addTypeAssertionNodes(clause, true, myPatternBindingNames);
}
PyExpression guard = clause.getGuardCondition();
if (guard != null) {
TransparentInstruction trueNode = addTransparentInstruction();
@@ -650,7 +651,7 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
elsePart.accept(this);
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
}
myBuilder.flowAbrupted();
collectInternalPendingEdges(node);
@@ -958,7 +959,7 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
myBuilder.addEdge(myBuilder.prevInstruction, i);
}
}
collectInternalPendingEdges(node);
}
@@ -1147,7 +1148,7 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
private TransparentInstruction addTransparentInstruction() {
return addTransparentInstruction(null);
}
private TransparentInstruction addTransparentInstruction(@Nullable PsiElement element) {
TransparentInstructionImpl instruction = new TransparentInstructionImpl(myBuilder, element, "");
myBuilder.instructions.add(instruction);
@@ -1162,11 +1163,11 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
}
/**
* Can be used to collect all pending edges
* Can be used to collect all pending edges
* that we used to build CFG for `node`,
* but are not relevant to other elements.
* Is almost equivalent to this:
*
*
* <pre>{@code
* visitPy...(node);
* myBuilder.startNode(node.nextSibling); // collectInternalPendingEdges does this, without needing nextSibling
@@ -6,9 +6,10 @@ import com.jetbrains.python.psi.PyAssertStatement
import com.jetbrains.python.psi.PyRaiseStatement
import com.jetbrains.python.psi.PyStatement
class PyRaiseInstruction private constructor(builder: ControlFlowBuilder, raiseOrAssert: PyStatement): InstructionImpl(builder, raiseOrAssert) {
constructor(builder: ControlFlowBuilder, raise: PyRaiseStatement): this(builder, raise as PyStatement)
constructor(builder: ControlFlowBuilder, assert: PyAssertStatement): this(builder, assert as PyStatement)
class PyRaiseInstruction private constructor(builder: ControlFlowBuilder, raiseOrAssert: PyStatement) : InstructionImpl(builder,
raiseOrAssert) {
constructor(builder: ControlFlowBuilder, raise: PyRaiseStatement) : this(builder, raise as PyStatement)
constructor(builder: ControlFlowBuilder, assert: PyAssertStatement) : this(builder, assert as PyStatement)
override fun getElementPresentation(): String = "raise: ${element}"
}
@@ -131,7 +131,8 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
PyExpression[] elements = ((PySequenceExpression)rhs).getElements();
List<PyType> types = new ArrayList<>(elements.length);
for (PyExpression element : elements) {
PyType type = PyLiteralType.isNone(element) ? PyBuiltinCache.getInstance(element).getNoneType() : getLiteralType(element, context);
PyType type =
PyLiteralType.isNone(element) ? PyBuiltinCache.getInstance(element).getNoneType() : getLiteralType(element, context);
if (type == null) {
return null;
}
@@ -201,7 +202,7 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
public static @Nullable Ref<PyType> createAssertionType(@Nullable PyType initial,
@Nullable PyType suggested,
boolean positive,
boolean forceStrictNarrow,
boolean forceStrictNarrow,
@NotNull TypeEvalContext context) {
if (suggested == null) return null;
if (positive) {
@@ -281,7 +282,7 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
}
return null;
}
private static @Nullable PyType intersect(@Nullable PyType initial, @Nullable PyType suggested) {
// TODO: if we had IntersectionType, here it would be created. Also, final classes can be handled here
if (initial instanceof PyNeverType) {
@@ -301,7 +302,9 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
/**
* @param transformToDefinition if true the result type will be Type[T], not T itself.
*/
private static @Nullable PyType transformTypeFromAssertion(@Nullable PyType type, boolean transformToDefinition, @NotNull TypeEvalContext context,
private static @Nullable PyType transformTypeFromAssertion(@Nullable PyType type,
boolean transformToDefinition,
@NotNull TypeEvalContext context,
@Nullable PyExpression typeElement) {
/*
* We need to distinguish:
@@ -348,7 +351,11 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
pushAssertion(expr, positive, false, isStrictNarrowingAllowed(), suggestedType);
}
private void pushAssertion(@Nullable PyExpression expr, boolean positive, boolean allowAnyExpr, boolean forceStrictNarrow, @NotNull Function<TypeEvalContext, PyType> suggestedType) {
private void pushAssertion(@Nullable PyExpression expr,
boolean positive,
boolean allowAnyExpr,
boolean forceStrictNarrow,
@NotNull Function<TypeEvalContext, PyType> suggestedType) {
expr = PyPsiUtils.flattenParens(expr);
if (expr instanceof PySequenceExpression seqExpr) {
PyExpression[] elements = seqExpr.getElements();
@@ -388,11 +395,11 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
return null;
};
}
private static @Nullable PsiElement skipNotAndParens(@Nullable PsiElement element) {
if (element == null) return null;
for (PsiElement e = element.getParent(); e != null; e = e.getParent()) {
if (!(e instanceof PyParenthesizedExpression) &&
if (!(e instanceof PyParenthesizedExpression) &&
!(e instanceof PyPrefixExpression prefixExpr && prefixExpr.getOperator() == PyTokenTypes.NOT_KEYWORD)) {
return e;
}
@@ -406,8 +413,10 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
if (parent instanceof PyConditionalExpression cond && PsiTreeUtil.isAncestor(cond.getCondition(), node, false)) return true;
if (parent instanceof PyBinaryExpression binExpr && (binExpr.isOperator(PyNames.AND) || binExpr.isOperator(PyNames.OR))) return true;
if (parent instanceof PyAssertStatement) return true;
if (parent instanceof PyGeneratorExpression gen &&
ContainerUtil.or(gen.getIfComponents(), it -> PsiTreeUtil.isAncestor(it.getTest(), node, false))) return true;
if (parent instanceof PyGeneratorExpression gen &&
ContainerUtil.or(gen.getIfComponents(), it -> PsiTreeUtil.isAncestor(it.getTest(), node, false))) {
return true;
}
return false;
}
@@ -100,7 +100,7 @@ public final class ReadWriteInstruction extends InstructionImpl {
public @NotNull ACCESS getAccess() {
return myAccess;
}
public static @NotNull ReadWriteInstruction read(final @NotNull ControlFlowBuilder builder,
final @Nullable PyElement element,
final @Nullable String name) {
@@ -112,14 +112,14 @@ public final class ReadWriteInstruction extends InstructionImpl {
final @Nullable String name) {
return new ReadWriteInstruction(builder, element, name, ACCESS.WRITE);
}
public static @NotNull ReadWriteInstruction newInstruction(final @NotNull ControlFlowBuilder builder,
final @Nullable PsiElement element,
final @Nullable String name,
final @NotNull ACCESS access) {
return new ReadWriteInstruction(builder, element, name, access);
}
public static @NotNull ReadWriteInstruction assertType(final @NotNull ControlFlowBuilder builder,
final @Nullable PsiElement element,
final @Nullable String name,
@@ -32,9 +32,9 @@ public class PyReachingDefsDfaInstance implements DfaMapInstance<ScopeVariable>
@Override
public DFAMap<ScopeVariable> fun(final DFAMap<ScopeVariable> map, final Instruction instruction) {
if (map == UNREACHABLE_MARKER) return map;
if (map == UNREACHABLE_MARKER) return map;
final PsiElement element = instruction.getElement();
if (element == null || ((PyFile) element.getContainingFile()).getLanguageLevel().isPython2()){
if (element == null || ((PyFile)element.getContainingFile()).getLanguageLevel().isPython2()) {
return processReducedMap(map, instruction, element);
}
if (PyDataFlowKt.isUnreachableForInspection(element, myContext)) {
@@ -50,11 +50,11 @@ public class PyReachingDefsDfaInstance implements DfaMapInstance<ScopeVariable>
for (Map.Entry<String, ScopeVariable> entry : map.entrySet()) {
final ScopeVariable value = entry.getValue();
// Support PEP-3110. (PY-1408)
if (value.isParameter()){
if (value.isParameter()) {
final PsiElement declaration = value.getDeclarations().iterator().next();
final PyExceptPart exceptPart = PyExceptPartNavigator.getPyExceptPartByTarget(declaration);
if (exceptPart != null){
if (!PsiTreeUtil.isAncestor(exceptPart, element, false)){
if (exceptPart != null) {
if (!PsiTreeUtil.isAncestor(exceptPart, element, false)) {
continue;
}
}
@@ -85,10 +85,10 @@ public class PyReachingDefsDfaInstance implements DfaMapInstance<ScopeVariable>
}
}
// Processing PyFunction
else if (element instanceof PyFunction){
else if (element instanceof PyFunction) {
name = ((PyFunction)element).getName();
}
if (name == null){
if (name == null) {
return map;
}
final ScopeVariable variable = map.get(name);
@@ -106,7 +106,8 @@ public class PyReachingDefsDfaInstance implements DfaMapInstance<ScopeVariable>
final boolean isParameter = variable != null && variable.isParameter();
if (variable == null) {
scopeVariable = new ScopeVariableImpl(name, isParameter, element);
} else {
}
else {
scopeVariable = new ScopeVariableImpl(name, isParameter, variable.getDeclarations());
}
map = map.asWritable();
@@ -33,7 +33,7 @@ public class PyReachingDefsSemilattice implements MapSemilattice<ScopeVariable>
return ins.get(0);
}
ins = ins.stream().filter( e -> e != PyReachingDefsDfaInstance.UNREACHABLE_MARKER).toList();
ins = ins.stream().filter(e -> e != PyReachingDefsDfaInstance.UNREACHABLE_MARKER).toList();
final Set<String> resultNames = getResultNames(ins);
if (resultNames == null || resultNames.isEmpty()) {
@@ -43,9 +43,11 @@ public interface Scope {
@NotNull TypeEvalContext typeEvalContext) throws DFALimitExceededException;
boolean hasGlobals();
boolean isGlobal(String name);
boolean hasNonLocals();
boolean isNonlocal(String name);
boolean containsDeclaration(String name);
@@ -35,26 +35,26 @@ public final class ScopeUtil {
private ScopeUtil() {
}
public static @Nullable PsiElement getParameterScope(final PsiElement element){
if (element instanceof PyNamedParameter){
public static @Nullable PsiElement getParameterScope(final PsiElement element) {
if (element instanceof PyNamedParameter) {
final PyFunction function = getParentOfType(element, PyFunction.class, false);
if (function != null){
if (function != null) {
return function;
}
}
final PyExceptPart exceptPart = PyExceptPartNavigator.getPyExceptPartByTarget(element);
if (exceptPart != null){
if (exceptPart != null) {
return exceptPart;
}
final PyForStatement forStatement = PyForStatementNavigator.getPyForStatementByIterable(element);
if (forStatement != null){
if (forStatement != null) {
return forStatement;
}
final PyListCompExpression listCompExpression = PyListCompExpressionNavigator.getPyListCompExpressionByVariable(element);
if (listCompExpression != null){
if (listCompExpression != null) {
return listCompExpression;
}
return null;
@@ -232,10 +232,10 @@ public class ScopeImpl implements Scope {
importStmt.accept(new PyVersionAwareElementVisitor(languageLevel) {
@Override
public void visitPyElement(@NotNull PyElement node) {
if (node instanceof PyImportedNameDefiner definer) {
importedNameDefiners.add(definer);
}
super.visitPyElement(node);
if (node instanceof PyImportedNameDefiner definer) {
importedNameDefiners.add(definer);
}
super.visitPyElement(node);
}
});
}
@@ -40,7 +40,7 @@ public class ScopeVariableImpl implements ScopeVariable {
@Override
public String toString() {
return (isParameter() ? "par" : "var") + "(" + myName+ ")[" + myDeclarations.size() + "]";
return (isParameter() ? "par" : "var") + "(" + myName + ")[" + myDeclarations.size() + "]";
}
@Override
@@ -28,7 +28,9 @@ import static com.jetbrains.python.psi.types.PyTypeUtil.notNullToRef;
public final class PyDecoratedFunctionTypeProvider extends PyTypeProviderBase {
@Override
public @Nullable Ref<PyType> getReferenceType(@NotNull PsiElement referenceTarget, @NotNull TypeEvalContext context, @Nullable PsiElement anchor) {
public @Nullable Ref<PyType> getReferenceType(@NotNull PsiElement referenceTarget,
@NotNull TypeEvalContext context,
@Nullable PsiElement anchor) {
if (!(referenceTarget instanceof PyDecoratable pyDecoratable)) {
return null;
}
@@ -85,10 +85,10 @@ public class PyFunctionTypeAnnotationParser extends PyParser {
assert atToken(PyTokenTypes.LPAR);
final SyntaxTreeBuilder.Marker listMark = myBuilder.mark();
myBuilder.advanceLexer();
final ExpressionParsing exprParser = getExpressionParser();
int paramCount = 0;
while (!(atAnyOfTokens(PyTokenTypes.RPAR, PyTokenTypes.RARROW, PyTokenTypes.STATEMENT_BREAK) || myBuilder.eof()) ) {
while (!(atAnyOfTokens(PyTokenTypes.RPAR, PyTokenTypes.RARROW, PyTokenTypes.STATEMENT_BREAK) || myBuilder.eof())) {
if (paramCount > 0) {
checkMatches(PyTokenTypes.COMMA, PyParsingBundle.message("PARSE.expected.comma"));
}
@@ -110,7 +110,8 @@ public class PyFunctionTypeAnnotationParser extends PyParser {
}
if (!parsed) {
myBuilder.error(PyParsingBundle.message("PARSE.expected.expression"));
recoverUntilMatches(PyParsingBundle.message("PARSE.expected.expression"), PyTokenTypes.COMMA, PyTokenTypes.RPAR, PyTokenTypes.RARROW, PyTokenTypes.STATEMENT_BREAK);
recoverUntilMatches(PyParsingBundle.message("PARSE.expected.expression"), PyTokenTypes.COMMA, PyTokenTypes.RPAR,
PyTokenTypes.RARROW, PyTokenTypes.STATEMENT_BREAK);
}
paramCount++;
}
@@ -31,8 +31,8 @@ public class PyFunctionTypeAnnotation extends PyElementImpl {
public @NotNull PyParameterTypeList getParameterTypeList() {
return findNotNullChildByClass(PyParameterTypeList.class);
}
}
public @Nullable PyExpression getReturnType() {
return findChildByClass(PyExpression.class);
}
@@ -64,7 +64,9 @@ public final class AddImportHelper {
}
public static @NotNull Comparator<String> getImportTextComparator(@NotNull PsiFile settingsAnchor) {
return PythonCodeStyleService.getInstance().isOptimizeImportsCaseSensitiveOrder(settingsAnchor) ? String.CASE_INSENSITIVE_ORDER : Comparator.naturalOrder();
return PythonCodeStyleService.getInstance().isOptimizeImportsCaseSensitiveOrder(settingsAnchor)
? String.CASE_INSENSITIVE_ORDER
: Comparator.naturalOrder();
}
private static @NotNull List<String> getSortNames(@NotNull PyImportStatementBase importStatement) {
@@ -161,7 +163,6 @@ public final class AddImportHelper {
if (parentElement != null) {
parentElement.addBefore(generator.createFromImportStatement(languageLevel, qualifier, name, asName), anchor);
}
}
public static @Nullable PsiElement getLocalInsertPosition(@NotNull PsiElement anchor) {
@@ -368,7 +369,8 @@ public final class AddImportHelper {
return getImportPriorityWithReason(importStatement, resolvedFileOrDir);
}
static @NotNull ImportPriorityChoice getImportPriorityWithReason(@NotNull PsiElement importLocation, @NotNull PsiFileSystemItem toImport) {
static @NotNull ImportPriorityChoice getImportPriorityWithReason(@NotNull PsiElement importLocation,
@NotNull PsiFileSystemItem toImport) {
final VirtualFile vFile = toImport.getVirtualFile();
if (vFile == null) {
return new ImportPriorityChoice(UNRESOLVED_SYMBOL_PRIORITY, toImport + " doesn't have an associated virtual file");
@@ -100,7 +100,9 @@ public class ImportCandidateHolder implements Comparable<ImportCandidateHolder>
* @param source known ImportElement to import the name; its 'as' clause is used if present.
* @return a properly qualified name.
*/
public static @NotNull String getQualifiedName(@NotNull String name, @Nullable QualifiedName importPath, @Nullable PyImportElement source) {
public static @NotNull String getQualifiedName(@NotNull String name,
@Nullable QualifiedName importPath,
@Nullable PyImportElement source) {
final StringBuilder sb = new StringBuilder();
if (source != null) {
final PsiElement parent = source.getParent();
@@ -34,9 +34,9 @@ public class ImportFromExistingAction implements QuestionAction {
private final boolean myImportLocally;
/**
* @param target element to become qualified as imported.
* @param sources clauses of import to be used.
* @param name relevant name ot the target element (e.g. of identifier in an expression).
* @param target element to become qualified as imported.
* @param sources clauses of import to be used.
* @param name relevant name ot the target element (e.g. of identifier in an expression).
* @param insertBefore import statement should be inserted right before this element. However, if it aims at an insertion statement in
* a group of inserts, a better insertion point belonging the group may be chosen, and it can be after the specified
* node. If null, the position will be chosen automatically.
@@ -201,5 +201,4 @@ public class ImportFromExistingAction implements QuestionAction {
myOnDoneCallback.run();
}
}
}
@@ -8,7 +8,7 @@ import com.jetbrains.python.psi.resolve.QualifiedNameFinder
/**
* @author Aleksei Kniazev
*/
class PyRelativeImportData private constructor(val relativeLocation: String, val relativeLevel: Int) {
class PyRelativeImportData private constructor(val relativeLocation: String, val relativeLevel: Int) {
val locationWithDots: String
get() = ".".repeat(relativeLevel) + relativeLocation
@@ -51,7 +51,7 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
while (scanner.find(index)) {
if (scanner.start() > 1) {
// handle escaping sequences PY-977
if ("{".equals(scanner.group(0)) && "\\N".equals(source.subSequence(scanner.start()-2, scanner.start()).toString())) {
if ("{".equals(scanner.group(0)) && "\\N".equals(source.subSequence(scanner.start() - 2, scanner.start()).toString())) {
skipClosingBrace = true;
target.append(source.subSequence(index, scanner.end()));
index = scanner.end();
@@ -66,8 +66,12 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
}
target.append(source.subSequence(index, scanner.start()));
if ("{".equals(scanner.group(0))) target.append("{{");
else target.append("}}");
if ("{".equals(scanner.group(0))) {
target.append("{{");
}
else {
target.append("}}");
}
index = scanner.end();
}
target.append(source.subSequence(index, source.length()));
@@ -75,6 +79,7 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
/**
* Converts format expressions inside a string
*
* @return a pair of string builder with resulting string expression and a flag which is true if formats inside use mapping by name.
*/
private static Pair<StringBuilder, Boolean> convertFormat(PyStringLiteralExpression stringLiteralExpression, String prefix) {
@@ -97,12 +102,12 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
sure("\"'".indexOf(quote) >= 0);
if (text.length() - openPos >= 6) {
// triple-quoted?
if (text.charAt(openPos+1) == quote && text.charAt(openPos+2) == quote) {
if (text.charAt(openPos + 1) == quote && text.charAt(openPos + 2) == quote) {
openPos += 2;
}
}
int index = openPos + 1; // from quote to first in-string char
StringBuilder out = new StringBuilder(text.subSequence(0, openPos+1));
StringBuilder out = new StringBuilder(text.subSequence(0, openPos + 1));
if (!hasPrefix) out.insert(0, prefix);
Matcher scanner = FORMAT_PATTERN.matcher(text);
while (scanner.find(index)) {
@@ -136,7 +141,9 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
if (f_width != null) {
out.append(f_width);
}
if ("i".equals(fConversion) || "u".equals(fConversion)) out.append("d");
if ("i".equals(fConversion) || "u".equals(fConversion)) {
out.append("d");
}
else if (!"s".equals(fConversion) && !"r".equals(fConversion)) out.append(fConversion);
final int lastIndexOf = out.lastIndexOf(":");
@@ -164,7 +171,7 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
int left = prev_range.getEndOffset() - full_start;
int right = next_range.getStartOffset() - full_start;
if (left < right) {
constants.get(fragment_no-1).append(full_text.subSequence(left, right));
constants.get(fragment_no - 1).append(full_text.subSequence(left, right));
}
fragment_no += 1;
prev_range = next_range;
@@ -173,7 +180,7 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
final int right = full_range.getEndOffset() - full_start;
if (left < right) {
// the barely possible case of last dangling "\"
constants.get(constants.size()-1).append(full_text.subSequence(left, right));
constants.get(constants.size() - 1).append(full_text.subSequence(left, right));
}
// join everything
@@ -219,12 +226,13 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
return false;
}
PyBinaryExpression binaryExpression =
PyBinaryExpression binaryExpression =
PsiTreeUtil.getParentOfType(psiFile.findElementAt(editor.getCaretModel().getOffset()), PyBinaryExpression.class, false);
if (binaryExpression == null) {
return false;
}
if (binaryExpression.getLeftExpression() instanceof PyStringLiteralExpression str && binaryExpression.getOperator() == PyTokenTypes.PERC) {
if (binaryExpression.getLeftExpression() instanceof PyStringLiteralExpression str &&
binaryExpression.getOperator() == PyTokenTypes.PERC) {
if ((!str.getText().isEmpty() && Character.toUpperCase(str.getText().charAt(0)) == 'B')) {
return false;
}
@@ -290,7 +298,9 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
else if (PyTypeUtil.isDict(rhsType)) {
target.append("(**").append(paramText).append(")");
}
else target.append("(").append(paramText).append(")"); // tuple is ok as is
else {
target.append("(").append(paramText).append(")"); // tuple is ok as is
}
// Correctly handle multiline implicitly concatenated string literals (PY-9176)
target.insert(0, '(').append(')');
final PyExpression parenthesized = elementGenerator.createExpressionFromText(LanguageLevel.forElement(element), target.toString());
@@ -313,13 +323,15 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
String separator = ""; // detect nontrivial whitespace around the "%"
Pair<String, PsiElement> crop = collectWhitespace(leftExpression);
String maybeSeparator = crop.getFirst();
if (maybeSeparator != null && !maybeSeparator.isEmpty() && !" ".equals(maybeSeparator))
if (maybeSeparator != null && !maybeSeparator.isEmpty() && !" ".equals(maybeSeparator)) {
separator = maybeSeparator;
}
else { // after "%"
crop = collectWhitespace(crop.getSecond());
maybeSeparator = crop.getFirst();
if (maybeSeparator != null && !maybeSeparator.isEmpty() && !" ".equals(maybeSeparator))
if (maybeSeparator != null && !maybeSeparator.isEmpty() && !" ".equals(maybeSeparator)) {
separator = maybeSeparator;
}
}
return separator;
}
@@ -329,8 +341,12 @@ public final class ConvertFormatOperatorToMethodIntention extends PyBaseIntentio
PsiElement seeker = start;
while (seeker != null) {
seeker = seeker.getNextSibling();
if (seeker instanceof PsiWhiteSpace) sb.append(seeker.getText());
else break;
if (seeker instanceof PsiWhiteSpace) {
sb.append(seeker.getText());
}
else {
break;
}
}
return Pair.create(sb.toString(), seeker);
}
@@ -23,14 +23,15 @@ public final class DeclarationConflictChecker {
/**
* For each reference in the collection, finds a definition of name visible from the point of the reference. Returns a list of
* such definitions.
* @param name what to look for.
*
* @param name what to look for.
* @param references references to check.
* @param ignored if an element defining the name is also listed here, ignore it.
* @param ignored if an element defining the name is also listed here, ignore it.
* @return a list of pairs (referring element, element that defines name).
*/
public static @NotNull List<Pair<PsiElement, PsiElement>> findDefinitions(@NotNull String name,
@NotNull Collection<? extends PsiReference> references,
@NotNull Set<PsiElement> ignored) {
@NotNull Collection<? extends PsiReference> references,
@NotNull Set<PsiElement> ignored) {
final List<Pair<PsiElement, PsiElement>> conflicts = new ArrayList<>();
for (PsiReference ref : references) {
final PsiElement refElement = ref.getElement();
@@ -93,7 +93,9 @@ public final class ImportFromToImportIntention extends PyBaseIntentionAction {
if (remaining_module instanceof PyQualifiedExpression) {
remaining_name = PyPsiUtils.toPath((PyQualifiedExpression)remaining_module);
}
else remaining_name = ""; // unqualified name: "...module"
else {
remaining_name = ""; // unqualified name: "...module"
}
separated_name = info.myModuleReference.getReferencedName();
failure = false;
if (separated_name == null) {
@@ -101,13 +103,17 @@ public final class ImportFromToImportIntention extends PyBaseIntentionAction {
failure = true;
}
}
if (strict && failure) return null;
else return new String[] {getDots(info.myRelativeLevel)+remaining_name, separated_name};
if (strict && failure) {
return null;
}
else {
return new String[]{getDots(info.myRelativeLevel) + remaining_name, separated_name};
}
}
private static String getDots(int level) {
String dots = "";
for (int i=0; i<level; i+=1) dots += "."; // this generally runs 1-2 times, so it's cheaper than allocating a StringBuilder
for (int i = 0; i < level; i += 1) dots += "."; // this generally runs 1-2 times, so it's cheaper than allocating a StringBuilder
return dots;
}
@@ -157,12 +163,15 @@ public final class ImportFromToImportIntention extends PyBaseIntentionAction {
/**
* Adds myModuleName as a qualifier to target.
*
* @param target_node what to qualify
*/
private static void qualifyTarget(ASTNode target_node, Project project, String qualifier) {
final PyElementGenerator generator = PyElementGenerator.getInstance(project);
target_node.addChild(generator.createDot(), target_node.getFirstChildNode());
target_node.addChild(sure(generator.createFromText(LanguageLevel.getDefault(), PyReferenceExpression.class, qualifier, new int[]{0,0}).getNode()), target_node.getFirstChildNode());
target_node.addChild(
sure(generator.createFromText(LanguageLevel.getDefault(), PyReferenceExpression.class, qualifier, new int[]{0, 0}).getNode()),
target_node.getFirstChildNode());
}
@Override
@@ -170,14 +179,17 @@ public final class ImportFromToImportIntention extends PyBaseIntentionAction {
InfoHolder info = InfoHolder.collect(getElementFromEditor(editor, file));
try {
String qualifier; // we don't always qualify with module name
sure(info.myModuleReference); sure(info.myModuleName);
sure(info.myModuleReference);
sure(info.myModuleName);
String[] relative_names = null; // [0] is remaining import path, [1] is imported module name
if (info.myRelativeLevel > 0) {
relative_names = getRelativeNames(true, info);
if (relative_names == null) throw new IncorrectOperationException("failed to get relative names");
qualifier = relative_names[1];
}
else qualifier = info.myModuleName;
else {
qualifier = info.myModuleName;
}
// find all unqualified references that lead to one of our import elements
final PyImportElement[] ielts = info.myFromImportStatement.getImportElements();
final PyStarImportElement star_ielt = info.myFromImportStatement.getStarImportElement();
@@ -211,7 +223,8 @@ public final class ImportFromToImportIntention extends PyBaseIntentionAction {
sure(feeler instanceof PyQualifiedExpression); // if for some crazy reason module name refers to numbers, etc, no point to continue.
top_qualifier = (PyQualifiedExpression)feeler;
feeler = top_qualifier.getQualifier();
} while (feeler != null);
}
while (feeler != null);
String top_name = top_qualifier.getName();
Collection<PsiReference> possible_targets = references.keySet();
if (!star_references.isEmpty()) {
@@ -262,7 +275,8 @@ public final class ImportFromToImportIntention extends PyBaseIntentionAction {
new_import = sure(generator.createFromText(level, PyImportStatement.class, "import " + info.myModuleName));
}
else {
new_import = sure(generator.createFromText(level, PyFromImportStatement.class, "from " + relative_names[0] + " import " + relative_names[1]));
new_import =
sure(generator.createFromText(level, PyFromImportStatement.class, "from " + relative_names[0] + " import " + relative_names[1]));
}
ASTNode parent = sure(info.myFromImportStatement.getParent().getNode());
ASTNode old_node = sure(info.myFromImportStatement.getNode());

Some files were not shown because too many files have changed in this diff Show More