mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-78235 PyAnyType
GitOrigin-RevId: cac1389d7f20e8054223e07a0bf3f86b7b3c5b51
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5f035ba041
commit
c028889a56
@@ -243,7 +243,8 @@ public final @NonNls class PyNames {
|
||||
|
||||
public static final String NOT_IMPLEMENTED_ERROR = "NotImplementedError";
|
||||
|
||||
public static final @NlsSafe String UNKNOWN_TYPE = "Any";
|
||||
public static final @NlsSafe String ANY_TYPE = "Any";
|
||||
public static final @NlsSafe String UNKNOWN_TYPE = "Unknown";
|
||||
|
||||
public static final @NlsSafe String UNNAMED_ELEMENT = "<unnamed>";
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.psi.types
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.ProcessingContext
|
||||
import com.jetbrains.python.PyNames
|
||||
import com.jetbrains.python.psi.AccessDirection
|
||||
import com.jetbrains.python.psi.PyExpression
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext
|
||||
import com.jetbrains.python.psi.resolve.RatedResolveResult
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Experimental
|
||||
class PyAnyType private constructor(override val name: String) : PyType {
|
||||
override fun resolveMember(
|
||||
name: String,
|
||||
location: PyExpression?,
|
||||
direction: AccessDirection,
|
||||
resolveContext: PyResolveContext,
|
||||
): List<RatedResolveResult> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun getCompletionVariants(completionPrefix: String?, location: PsiElement, context: ProcessingContext): Array<Any> {
|
||||
return emptyArray()
|
||||
}
|
||||
|
||||
override val isBuiltin: Boolean = false
|
||||
|
||||
override fun assertValid(message: String?) {
|
||||
}
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? =
|
||||
if (this === Any) visitor.visitAnyType()
|
||||
else visitor.visitUnknownType()
|
||||
|
||||
companion object {
|
||||
val Any: PyAnyType = PyAnyType(PyNames.ANY_TYPE)
|
||||
val Unknown: PyAnyType = PyAnyType(PyNames.UNKNOWN_TYPE)
|
||||
}
|
||||
}
|
||||
@@ -80,14 +80,14 @@ public interface PyCallableType extends PyType {
|
||||
builder.append(name);
|
||||
builder.append(": ");
|
||||
}
|
||||
builder.append(type != null ? type.getName() : PyNames.UNKNOWN_TYPE);
|
||||
builder.append(type != null ? type.getName() : PyNames.ANY_TYPE);
|
||||
return builder.toString();
|
||||
}
|
||||
return PyNames.UNKNOWN_TYPE;
|
||||
return PyNames.ANY_TYPE;
|
||||
},
|
||||
", ") :
|
||||
"...",
|
||||
returnType != null ? returnType.getName() : PyNames.UNKNOWN_TYPE);
|
||||
returnType != null ? returnType.getName() : PyNames.ANY_TYPE);
|
||||
}
|
||||
|
||||
default @Nullable PyCallable getCallable() {
|
||||
|
||||
@@ -64,7 +64,7 @@ interface PyType {
|
||||
* @param context to share state between nested invocations
|
||||
* @return completion variants good for [com.intellij.psi.PsiReference.getVariants] return value.
|
||||
*/
|
||||
fun getCompletionVariants(completionPrefix: String?, location: PsiElement, context: ProcessingContext): Array<out @JvmWildcard Any>
|
||||
fun getCompletionVariants(completionPrefix: String?, location: PsiElement, context: ProcessingContext): Array<out Any>
|
||||
|
||||
@get:NlsSafe
|
||||
val name: @NlsSafe String?
|
||||
|
||||
@@ -1,85 +1,93 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.psi.types;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
package com.jetbrains.python.psi.types
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* Similarly to {@link com.intellij.psi.PsiElementVisitor}, implements double dispatching for the {@link PyType} hierarchy.
|
||||
* <p>
|
||||
* 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>
|
||||
* Similarly to [com.intellij.psi.PsiElementVisitor], implements double dispatching for the [PyType] hierarchy.
|
||||
*
|
||||
*
|
||||
* Because the "unknown" type is historically represented as `null` in the type system, `PyTypeVisitor.visitPyType(type, visitor)`
|
||||
* should be used instead of direct `type.acceptTypeVisitor(visitor)` to properly account for possible `null` values.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* Most actual implementations should extend [PyTypeVisitorExt].
|
||||
*
|
||||
*
|
||||
* There are helper [PyRecursiveTypeVisitor] and [PyCloningTypeVisitor] for recursive type
|
||||
* traversal and deep cloning of a type respectively.
|
||||
*
|
||||
*
|
||||
* @see PyRecursiveTypeVisitor
|
||||
*
|
||||
* @see PyCloningTypeVisitor
|
||||
* @see PyType#acceptTypeVisitor(PyTypeVisitor)
|
||||
* @see #visit(PyType, PyTypeVisitor)
|
||||
* @see #visitUnknownType()
|
||||
*
|
||||
* @see PyType.acceptTypeVisitor
|
||||
* @see .visit
|
||||
* @see .visitUnknownType
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public abstract class PyTypeVisitor<T> {
|
||||
/**
|
||||
* Use this method instead of {@link PyType#acceptTypeVisitor(PyTypeVisitor)} to take into account
|
||||
* "unknown" {@code null} types, for which {@link #visitUnknownType()} should be called.
|
||||
*/
|
||||
public static <T> T visit(@Nullable PyType type, @NotNull PyTypeVisitor<T> visitor) {
|
||||
return type == null ? visitor.visitUnknownType() : type.acceptTypeVisitor(visitor);
|
||||
abstract class PyTypeVisitor<T> {
|
||||
open fun visitPyType(type: PyType): T? {
|
||||
return null
|
||||
}
|
||||
|
||||
public T visitPyType(@NotNull PyType type) {
|
||||
return null;
|
||||
open fun visitPyClassType(classType: PyClassType): T? {
|
||||
return visitPyClassLikeType(classType)
|
||||
}
|
||||
|
||||
public T visitPyClassType(@NotNull PyClassType classType) {
|
||||
return visitPyClassLikeType(classType);
|
||||
}
|
||||
|
||||
public T visitPyClassLikeType(@NotNull PyClassLikeType classLikeType) {
|
||||
open fun visitPyClassLikeType(classLikeType: PyClassLikeType): T? {
|
||||
// Don't treat PyClassLikeType as PyCallableType. It's usually not what a visitor's user expects.
|
||||
return visitPyType(classLikeType);
|
||||
return visitPyType(classLikeType)
|
||||
}
|
||||
|
||||
public T visitPyFunctionType(@NotNull PyFunctionType functionType) {
|
||||
return visitPyCallableType(functionType);
|
||||
open fun visitPyFunctionType(functionType: PyFunctionType): T? {
|
||||
return visitPyCallableType(functionType)
|
||||
}
|
||||
|
||||
public T visitPyCallableType(@NotNull PyCallableType callableType) {
|
||||
return visitPyType(callableType);
|
||||
open fun visitPyCallableType(callableType: PyCallableType): T? {
|
||||
return visitPyType(callableType)
|
||||
}
|
||||
|
||||
public T visitPyTypeVarType(@NotNull PyTypeVarType typeVarType) {
|
||||
return visitPyTypeParameterType(typeVarType);
|
||||
open fun visitPyTypeVarType(typeVarType: PyTypeVarType): T? {
|
||||
return visitPyTypeParameterType(typeVarType)
|
||||
}
|
||||
|
||||
public T visitPyTypeVarTupleType(@NotNull PyTypeVarTupleType typeVarTupleType) {
|
||||
return visitPyTypeParameterType(typeVarTupleType);
|
||||
open fun visitPyTypeVarTupleType(typeVarTupleType: PyTypeVarTupleType): T? {
|
||||
return visitPyTypeParameterType(typeVarTupleType)
|
||||
}
|
||||
|
||||
public T visitPyTypeParameterType(@NotNull PyTypeParameterType typeParameterType) {
|
||||
return visitPyType(typeParameterType);
|
||||
open fun visitPyTypeParameterType(typeParameterType: PyTypeParameterType): T? {
|
||||
return visitPyType(typeParameterType)
|
||||
}
|
||||
|
||||
public T visitPyUnpackedTupleType(@NotNull PyUnpackedTupleType unpackedTupleType) {
|
||||
return visitPyType(unpackedTupleType);
|
||||
open fun visitPyUnpackedTupleType(unpackedTupleType: PyUnpackedTupleType): T? {
|
||||
return visitPyType(unpackedTupleType)
|
||||
}
|
||||
|
||||
public T visitPyCallableParameterListType(@NotNull PyCallableParameterListType callableParameterListType) {
|
||||
return visitPyType(callableParameterListType);
|
||||
open fun visitPyCallableParameterListType(callableParameterListType: PyCallableParameterListType): T? {
|
||||
return visitPyType(callableParameterListType)
|
||||
}
|
||||
|
||||
public T visitPyNeverType(@NotNull PyNeverType neverType) {
|
||||
return visitPyType(neverType);
|
||||
open fun visitPyNeverType(neverType: PyNeverType): T? {
|
||||
return visitPyType(neverType)
|
||||
}
|
||||
|
||||
public T visitUnknownType() {
|
||||
return null;
|
||||
open fun visitAnyType(): T? {
|
||||
return null
|
||||
}
|
||||
|
||||
open fun visitUnknownType(): T? {
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Use this method instead of [PyType.acceptTypeVisitor] to take into account
|
||||
* "unknown" `null` types, for which [.visitUnknownType] should be called.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun <T> visit(type: PyType?, visitor: PyTypeVisitor<T>): T? =
|
||||
if (type == null) visitor.visitUnknownType() else type.acceptTypeVisitor(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public abstract class PyTypeRenderer extends PyTypeVisitorExt<@NotNull HtmlChunk
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HtmlChunk visitPyIntersectionType(com.jetbrains.python.psi.types.@NotNull PyIntersectionType intersectionType) {
|
||||
public @NotNull HtmlChunk visitPyIntersectionType(@NotNull PyIntersectionType intersectionType) {
|
||||
// There is no way to represent intersections through the standard type hints at the moment
|
||||
return visitUnknownType();
|
||||
}
|
||||
@@ -465,9 +465,15 @@ public abstract class PyTypeRenderer extends PyTypeVisitorExt<@NotNull HtmlChunk
|
||||
return result.toFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlChunk visitAnyType() {
|
||||
return HtmlChunk.raw(isRenderingFqn() ? PyTypingTypeProvider.ANY : PyNames.ANY_TYPE); //NON-NLS
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlChunk visitUnknownType() {
|
||||
return HtmlChunk.raw(isRenderingFqn() ? "typing.Any" : "Any"); //NON-NLS
|
||||
// TODO: show "Unknown" instead of "typing.Any" when we convert to it
|
||||
return visitAnyType();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -533,10 +539,7 @@ public abstract class PyTypeRenderer extends PyTypeVisitorExt<@NotNull HtmlChunk
|
||||
case ", " -> {
|
||||
yield styled(separator, PyHighlighter.PY_COMMA);
|
||||
}
|
||||
case " | " -> {
|
||||
yield styled(separator, PyHighlighter.PY_OPERATION_SIGN);
|
||||
}
|
||||
case " & " -> {
|
||||
case " | ", " & " -> {
|
||||
yield styled(separator, PyHighlighter.PY_OPERATION_SIGN);
|
||||
}
|
||||
default -> {
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ public final class PyDocstringTypesInspection extends PyInspection {
|
||||
return type.getName();
|
||||
}
|
||||
else {
|
||||
return PyNames.UNKNOWN_TYPE;
|
||||
return PyNames.ANY_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ public final class PyCallableParameterListTypeImpl implements PyCallableParamete
|
||||
return String.format("[%s]",
|
||||
StringUtil.join(myParameters, param -> {
|
||||
PyType type = param.getType(context);
|
||||
return type != null ? type.getName() : PyNames.UNKNOWN_TYPE;
|
||||
return type != null ? type.getName() : PyNames.ANY_TYPE;
|
||||
},
|
||||
", "));
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ package com.jetbrains.python.psi.types
|
||||
class PyConcatenateType(val firstTypes: List<PyType?>, val paramSpec: PyParamSpecType?) : PyCallableParameterVariadicType {
|
||||
override val name: String = "Concatenate(${firstTypes.joinToString { it?.name ?: "Any" }}, ${paramSpec?.name ?: "..."})"
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T {
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? {
|
||||
if (visitor is PyTypeVisitorExt) {
|
||||
return visitor.visitPyConcatenateType(this)
|
||||
}
|
||||
|
||||
+1
-1
@@ -41,6 +41,6 @@ public final class PyDynamicallyEvaluatedType extends PyUnionType {
|
||||
@Override
|
||||
public String getName() {
|
||||
PyType res = excludeNull();
|
||||
return res != null ? res.getName() : PyNames.UNKNOWN_TYPE;
|
||||
return res != null ? res.getName() : PyNames.ANY_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class PyIntersectionType private constructor(members: Collection<PyType?>) : PyT
|
||||
}
|
||||
}
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T {
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? {
|
||||
if (visitor is PyTypeVisitorExt<T>) {
|
||||
return visitor.visitPyIntersectionType(this)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class PyLiteralStringType private constructor(val cls: PyClass) : PyClassTypeImp
|
||||
return Objects.hash(super.hashCode(), cls)
|
||||
}
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T {
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? {
|
||||
if (visitor is PyTypeVisitorExt) {
|
||||
return visitor.visitPyLiteralStringType(this)
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class PyLiteralType private constructor(cls: PyClass, val expression: PyExpressi
|
||||
|
||||
override fun hashCode(): Int = 31 * pyClass.hashCode()
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T {
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? {
|
||||
if (visitor is PyTypeVisitorExt) {
|
||||
return visitor.visitPyLiteralType(this)
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class PyNarrowedType private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T {
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? {
|
||||
if (visitor is PyTypeVisitorExt) {
|
||||
return visitor.visitPyNarrowedType(this)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class PyTupleType extends PyClassTypeImpl implements PyCollectionType {
|
||||
}
|
||||
|
||||
private static @Nullable String getTypeName(@Nullable PyType type) {
|
||||
return type == null ? PyNames.UNKNOWN_TYPE : type.getName();
|
||||
return type == null ? PyNames.ANY_TYPE : type.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1269,12 +1269,12 @@ object PyTypeChecker {
|
||||
generics: GenericsImpl,
|
||||
) {
|
||||
PyRecursiveTypeVisitor.traverse(type, context, object : PyTypeTraverser() {
|
||||
override fun visitPyTypeVarType(typeVarType: PyTypeVarType): PyRecursiveTypeVisitor.Traversal {
|
||||
override fun visitPyTypeVarType(typeVarType: PyTypeVarType): PyRecursiveTypeVisitor.Traversal? {
|
||||
generics.typeVars.add(typeVarType)
|
||||
return super.visitPyTypeVarType(typeVarType)
|
||||
}
|
||||
|
||||
override fun visitPyTypeVarTupleType(typeVarTupleType: PyTypeVarTupleType): PyRecursiveTypeVisitor.Traversal {
|
||||
override fun visitPyTypeVarTupleType(typeVarTupleType: PyTypeVarTupleType): PyRecursiveTypeVisitor.Traversal? {
|
||||
generics.typeVarTuples.add(typeVarTupleType)
|
||||
return super.visitPyTypeVarTupleType(typeVarTupleType)
|
||||
}
|
||||
|
||||
@@ -546,7 +546,7 @@ public final class PyTypeParser {
|
||||
final String name = token.getText().toString();
|
||||
final TextRange range = token.getRange();
|
||||
|
||||
if (PyNames.UNKNOWN_TYPE.equals(name)) {
|
||||
if (PyNames.ANY_TYPE.equals(name)) {
|
||||
return EMPTY_RESULT;
|
||||
}
|
||||
else if (PyNames.NONE.equals(name)) {
|
||||
|
||||
@@ -318,7 +318,7 @@ class PyTypedDictType(
|
||||
val hasErrors: Boolean get() = valueTypeErrors.isNotEmpty() || missingKeys.isNotEmpty() || extraKeys.isNotEmpty()
|
||||
}
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T {
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? {
|
||||
if (visitor is PyTypeVisitorExt) {
|
||||
return visitor.visitPyTypedDictType(this)
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ class PyTypingNewType(
|
||||
return 31 * classType.hashCode() + name.hashCode()
|
||||
}
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T {
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? {
|
||||
if (visitor is PyTypeVisitorExt) {
|
||||
return visitor.visitPyTypingNewType(this)
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ class PyUnsafeUnionType private constructor(members: Collection<PyType?>) : PyTy
|
||||
}
|
||||
}
|
||||
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T {
|
||||
override fun <T> acceptTypeVisitor(visitor: PyTypeVisitor<T>): T? {
|
||||
if (visitor is PyTypeVisitorExt<T>) {
|
||||
return visitor.visitPyUnsafeUnionType(this)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user