mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Links for function types in quickdoc (PY-3404).
This commit is contained in:
@@ -219,7 +219,7 @@ class PyDocumentationBuilder {
|
||||
}
|
||||
}
|
||||
else if (followed != null && outer instanceof PyReferenceExpression) {
|
||||
myBody.addItem("\nInferred type: ");
|
||||
myBody.addItem(combUp("\nInferred type: "));
|
||||
PythonDocumentationProvider.describeExpressionTypeWithLinks(myBody, (PyReferenceExpression)outer, TypeEvalContext.slow());
|
||||
}
|
||||
if (myBody.isEmpty() && myEpilog.isEmpty()) {
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
package com.jetbrains.python.documentation;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyNamedParameter;
|
||||
import com.jetbrains.python.psi.PyParameter;
|
||||
import com.jetbrains.python.psi.types.*;
|
||||
import com.jetbrains.python.toolbox.ChainIterable;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.jetbrains.python.documentation.DocumentationBuilderKit.$;
|
||||
import static com.jetbrains.python.documentation.DocumentationBuilderKit.combUp;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class PyTypeModelBuilder {
|
||||
@NonNls static final String UNKNOWN = "unknown";
|
||||
private final Map<PyType, TypeModel> myVisited = Maps.newHashMap();
|
||||
private final TypeEvalContext myContext;
|
||||
|
||||
PyTypeModelBuilder(TypeEvalContext context) {
|
||||
this.myContext = context;
|
||||
}
|
||||
|
||||
abstract static class TypeModel {
|
||||
abstract void accept(TypeVisitor visitor);
|
||||
|
||||
public String asString() {
|
||||
TypeToStringVisitor visitor = new TypeToStringVisitor();
|
||||
this.accept(visitor);
|
||||
return visitor.getString();
|
||||
}
|
||||
|
||||
public void toBodyWithLinks(@NotNull ChainIterable<String> body, @NotNull PsiElement anchor) {
|
||||
TypeToBodyWithLinksVisitor visitor = new TypeToBodyWithLinksVisitor(body, anchor);
|
||||
this.accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
static class OneOf extends TypeModel {
|
||||
private Collection<TypeModel> oneOfTypes;
|
||||
|
||||
private OneOf(Collection<TypeModel> oneOfTypes) {
|
||||
this.oneOfTypes = oneOfTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept(TypeVisitor visitor) {
|
||||
visitor.oneOf(this);
|
||||
}
|
||||
}
|
||||
|
||||
static class CollectionOf extends TypeModel {
|
||||
private String collectionName;
|
||||
private TypeModel elementType;
|
||||
|
||||
private CollectionOf(String collectionName, TypeModel elementType) {
|
||||
this.collectionName = collectionName;
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept(TypeVisitor visitor) {
|
||||
visitor.collectionOf(this);
|
||||
}
|
||||
}
|
||||
|
||||
static class NamedType extends TypeModel {
|
||||
private String name;
|
||||
|
||||
private NamedType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept(TypeVisitor visitor) {
|
||||
visitor.name(this.name);
|
||||
}
|
||||
}
|
||||
|
||||
private static TypeModel _(String name) {
|
||||
return new NamedType(name);
|
||||
}
|
||||
|
||||
static class FunctionType extends TypeModel {
|
||||
private TypeModel returnType;
|
||||
private Collection<TypeModel> parameters;
|
||||
|
||||
FunctionType(@NotNull TypeModel returnType, Collection<TypeModel> parameters) {
|
||||
this.returnType = returnType;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept(TypeVisitor visitor) {
|
||||
visitor.function(this);
|
||||
}
|
||||
}
|
||||
|
||||
static class ParamType extends TypeModel {
|
||||
private final String name;
|
||||
private final TypeModel type;
|
||||
|
||||
|
||||
private ParamType(String name, @Nullable TypeModel type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept(TypeVisitor visitor) {
|
||||
visitor.param(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds tree-like type model for PyType
|
||||
*
|
||||
* @param type
|
||||
* @param allowUnions
|
||||
* @return
|
||||
*/
|
||||
public TypeModel build(@Nullable PyType type,
|
||||
boolean allowUnions) {
|
||||
final TypeModel evaluated = myVisited.get(type);
|
||||
if (evaluated != null) {
|
||||
return evaluated;
|
||||
}
|
||||
if (myVisited.containsKey(type)) { //already evaluating?
|
||||
return type != null ? _(type.getName()) : _(UNKNOWN);
|
||||
}
|
||||
myVisited.put(type, null); //mark as evaluating
|
||||
|
||||
TypeModel result = null;
|
||||
if (type instanceof PyTypeReference) {
|
||||
final PyType resolved = ((PyTypeReference)type).resolve(null, myContext);
|
||||
if (resolved != null) {
|
||||
result = build(resolved, true);
|
||||
}
|
||||
}
|
||||
else if (type instanceof PyCollectionType) {
|
||||
final String name = type.getName();
|
||||
final PyType elementType = ((PyCollectionType)type).getElementType(myContext);
|
||||
if (elementType != null) {
|
||||
result = new CollectionOf(name, build(elementType, true));
|
||||
}
|
||||
}
|
||||
else if (type instanceof PyUnionType && allowUnions) {
|
||||
if (type instanceof PyDynamicallyEvaluatedType) {
|
||||
result = build(((PyDynamicallyEvaluatedType)type).exclude(null, myContext), true);
|
||||
}
|
||||
else {
|
||||
result = new OneOf(
|
||||
Collections2.transform(((PyUnionType)type).getMembers(), new Function<PyType, TypeModel>() {
|
||||
@Override
|
||||
public TypeModel apply(PyType t) {
|
||||
return build(t, false);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
result = type != null ? _(type.getName()) : _(UNKNOWN);
|
||||
}
|
||||
myVisited.put(type, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public TypeModel build(PyFunction function) {
|
||||
final PyType returnType = function.getReturnType(myContext, null);
|
||||
return new FunctionType(build(returnType, true), Collections2.transform(Lists.newArrayList(function.getParameterList().getParameters()),
|
||||
new Function<PyParameter, TypeModel>() {
|
||||
@Override
|
||||
public TypeModel apply(PyParameter p) {
|
||||
final PyNamedParameter np = p.getAsNamed();
|
||||
if (np != null) {
|
||||
TypeModel paramType =
|
||||
_(UNKNOWN);
|
||||
final PyType t = np.getType(myContext);
|
||||
if (t != null) {
|
||||
paramType = build(t, true);
|
||||
}
|
||||
return new ParamType(np.getName(), paramType);
|
||||
}
|
||||
return new ParamType(p.toString(), null);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private interface TypeVisitor {
|
||||
void oneOf(OneOf oneOf);
|
||||
|
||||
void collectionOf(CollectionOf collectionOf);
|
||||
|
||||
void name(String name);
|
||||
|
||||
void function(FunctionType type);
|
||||
|
||||
void param(ParamType text);
|
||||
}
|
||||
|
||||
private static class TypeToStringVisitor extends TypeNameVisitor {
|
||||
private final StringBuilder myStringBuilder = new StringBuilder();
|
||||
|
||||
@Override
|
||||
protected void add(String s) {
|
||||
myStringBuilder.append(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addType(String name) {
|
||||
add(name);
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return myStringBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TypeToBodyWithLinksVisitor extends TypeNameVisitor {
|
||||
private ChainIterable<String> myBody;
|
||||
private PsiElement myAnchor;
|
||||
|
||||
public TypeToBodyWithLinksVisitor(ChainIterable<String> body, PsiElement anchor) {
|
||||
myBody = body;
|
||||
myAnchor = anchor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void add(String s) {
|
||||
myBody.addItem(combUp(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addType(String name) {
|
||||
PyType type = PyTypeParser.getTypeByName(myAnchor, name);
|
||||
if (type instanceof PyClassType) {
|
||||
myBody.addWith(new DocumentationBuilderKit.LinkWrapper(PythonDocumentationProvider.LINK_TYPE_TYPENAME + name),
|
||||
$(name));
|
||||
}
|
||||
else {
|
||||
add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class TypeNameVisitor implements TypeVisitor {
|
||||
@Override
|
||||
public void oneOf(OneOf oneOf) {
|
||||
add("one of (");
|
||||
processListCommaSeparated(oneOf.oneOfTypes);
|
||||
add(")");
|
||||
}
|
||||
|
||||
private void processListCommaSeparated(Collection<TypeModel> list) {
|
||||
boolean first = true;
|
||||
for (TypeModel t : list) {
|
||||
if (!first) {
|
||||
add(", ");
|
||||
}
|
||||
else {
|
||||
first = false;
|
||||
}
|
||||
|
||||
t.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void add(String s);
|
||||
|
||||
@Override
|
||||
public void collectionOf(CollectionOf collectionOf) {
|
||||
addType(collectionOf.collectionName);
|
||||
add(" of ");
|
||||
collectionOf.elementType.accept(this);
|
||||
}
|
||||
|
||||
protected abstract void addType(String name);
|
||||
|
||||
@Override
|
||||
public void name(String name) {
|
||||
addType(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void function(FunctionType function) {
|
||||
add("(");
|
||||
processListCommaSeparated(function.parameters);
|
||||
add(") -> ");
|
||||
function.returnType.accept(this);
|
||||
add("\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void param(ParamType param) {
|
||||
add(param.name);
|
||||
if (param.type != null) {
|
||||
add(": ");
|
||||
param.type.accept(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.jetbrains.python.documentation;
|
||||
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.lang.documentation.AbstractDocumentationProvider;
|
||||
import com.intellij.lang.documentation.ExternalDocumentationProvider;
|
||||
@@ -19,7 +17,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
|
||||
import com.jetbrains.python.console.PydevConsoleRunner;
|
||||
@@ -57,8 +54,6 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
@NonNls private static final String RST_PREFIX = ":";
|
||||
@NonNls private static final String EPYDOC_PREFIX = "@";
|
||||
|
||||
@NonNls private static final String UNKNOWN = "unknown";
|
||||
|
||||
// provides ctrl+hover info
|
||||
public String getQuickNavigateInfo(final PsiElement element, PsiElement originalElement) {
|
||||
if (element instanceof PyFunction) {
|
||||
@@ -125,7 +120,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
cat.addItem(escaper.apply(PyUtil.getReadableRepr(fun.getParameterList(), false)));
|
||||
if (!PyNames.INIT.equals(name)) {
|
||||
cat.addItem(escaper.apply("\nInferred type: "));
|
||||
cat.addItem(escaper.apply(getTypeDescription(fun)));
|
||||
getTypeDescription(fun, cat);
|
||||
}
|
||||
return cat;
|
||||
}
|
||||
@@ -156,30 +151,24 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
|
||||
public static String getTypeDescription(@NotNull PyFunction fun) {
|
||||
final TypeEvalContext context = TypeEvalContext.slow();
|
||||
final PyType returnType = fun.getReturnType(context, null);
|
||||
return String.format("(%s) -> %s\n",
|
||||
StringUtil.join(fun.getParameterList().getParameters(),
|
||||
new Function<PyParameter, String>() {
|
||||
@Override
|
||||
public String fun(PyParameter p) {
|
||||
final PyNamedParameter np = p.getAsNamed();
|
||||
if (np != null) {
|
||||
String name = UNKNOWN;
|
||||
final PyType t = np.getType(context);
|
||||
if (t != null) {
|
||||
name = getTypeName(t, context);
|
||||
}
|
||||
return String.format("%s: %s", np.getName(), name);
|
||||
}
|
||||
return p.toString();
|
||||
}
|
||||
}, ", "),
|
||||
returnType != null ? getTypeName(returnType, context) : UNKNOWN);
|
||||
PyTypeModelBuilder builder = new PyTypeModelBuilder(context);
|
||||
return builder.build(fun).asString();
|
||||
}
|
||||
|
||||
public static void getTypeDescription(@NotNull PyFunction fun, ChainIterable<String> body) {
|
||||
final TypeEvalContext context = TypeEvalContext.slow();
|
||||
PyTypeModelBuilder builder = new PyTypeModelBuilder(context);
|
||||
builder.build(fun).toBodyWithLinks(body, fun);
|
||||
}
|
||||
|
||||
public static String getTypeName(@Nullable PyType type, @NotNull final TypeEvalContext context) {
|
||||
TypeNameBuilder builder = new TypeNameBuilder(context);
|
||||
return builder.build(type, true).asString();
|
||||
PyTypeModelBuilder.TypeModel typeModel = buildTypeModel(type, context);
|
||||
return typeModel.asString();
|
||||
}
|
||||
|
||||
private static PyTypeModelBuilder.TypeModel buildTypeModel(PyType type, TypeEvalContext context) {
|
||||
PyTypeModelBuilder builder = new PyTypeModelBuilder(context);
|
||||
return builder.build(type, true);
|
||||
}
|
||||
|
||||
public static void describeExpressionTypeWithLinks(ChainIterable<String> body,
|
||||
@@ -192,212 +181,10 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
public static void describeTypeWithLinks(ChainIterable<String> body,
|
||||
PsiElement anchor,
|
||||
PyType type, TypeEvalContext context) {
|
||||
TypeNameBuilder builder = new TypeNameBuilder(context);
|
||||
PyTypeModelBuilder builder = new PyTypeModelBuilder(context);
|
||||
builder.build(type, true).toBodyWithLinks(body, anchor);
|
||||
}
|
||||
|
||||
private static class TypeNameBuilder {
|
||||
private final Map<PyType, Type> myVisited = Maps.newHashMap();
|
||||
private final TypeEvalContext myContext;
|
||||
|
||||
private TypeNameBuilder(TypeEvalContext context) {
|
||||
this.myContext = context;
|
||||
}
|
||||
|
||||
private abstract static class Type {
|
||||
abstract void accept(TypeVisitor visitor);
|
||||
|
||||
public String asString() {
|
||||
TypeToStringVisitor visitor = new TypeToStringVisitor();
|
||||
this.accept(visitor);
|
||||
return visitor.getString();
|
||||
}
|
||||
|
||||
public void toBodyWithLinks(@NotNull ChainIterable<String> body, @NotNull PsiElement anchor) {
|
||||
TypeToBodyWithLinksVisitor visitor = new TypeToBodyWithLinksVisitor(body, anchor);
|
||||
this.accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
private static class OneOf extends Type {
|
||||
private Collection<Type> oneOfTypes;
|
||||
|
||||
private OneOf(Collection<Type> oneOfTypes) {
|
||||
this.oneOfTypes = oneOfTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept(TypeVisitor visitor) {
|
||||
visitor.oneOf(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CollectionOf extends Type {
|
||||
private String collectionName;
|
||||
private Type elementType;
|
||||
|
||||
private CollectionOf(String collectionName, Type elementType) {
|
||||
this.collectionName = collectionName;
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept(TypeVisitor visitor) {
|
||||
visitor.collectionOf(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NamedType extends Type {
|
||||
private String name;
|
||||
|
||||
private NamedType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
void accept(TypeVisitor visitor) {
|
||||
visitor.name(this.name);
|
||||
}
|
||||
}
|
||||
|
||||
private static Type _(String name) {
|
||||
return new NamedType(name);
|
||||
}
|
||||
|
||||
private Type build(@Nullable PyType type,
|
||||
boolean allowUnions) {
|
||||
final Type evaluated = myVisited.get(type);
|
||||
if (evaluated != null) {
|
||||
return evaluated;
|
||||
}
|
||||
if (myVisited.containsKey(type)) { //already evaluating?
|
||||
return type != null ? _(type.getName()) : _(UNKNOWN);
|
||||
}
|
||||
myVisited.put(type, null); //mark as evaluating
|
||||
|
||||
Type result = null;
|
||||
if (type instanceof PyTypeReference) {
|
||||
final PyType resolved = ((PyTypeReference)type).resolve(null, myContext);
|
||||
if (resolved != null) {
|
||||
result = build(resolved, true);
|
||||
}
|
||||
}
|
||||
else if (type instanceof PyCollectionType) {
|
||||
final String name = type.getName();
|
||||
final PyType elementType = ((PyCollectionType)type).getElementType(myContext);
|
||||
if (elementType != null) {
|
||||
result = new CollectionOf(name, build(elementType, true));
|
||||
}
|
||||
}
|
||||
else if (type instanceof PyUnionType && allowUnions) {
|
||||
if (type instanceof PyDynamicallyEvaluatedType) {
|
||||
result = build(((PyDynamicallyEvaluatedType)type).exclude(null, myContext), true);
|
||||
}
|
||||
else {
|
||||
result = new OneOf(Collections2.transform(((PyUnionType)type).getMembers(), new com.google.common.base.Function<PyType, Type>() {
|
||||
@Override
|
||||
public Type apply(PyType t) {
|
||||
return build(t, false);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
result = type != null ? _(type.getName()) : _(UNKNOWN);
|
||||
}
|
||||
myVisited.put(type, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private interface TypeVisitor {
|
||||
void oneOf(OneOf oneOf);
|
||||
|
||||
void collectionOf(CollectionOf collectionOf);
|
||||
|
||||
void name(String name);
|
||||
}
|
||||
|
||||
private static class TypeToStringVisitor extends TypeNameVisitor {
|
||||
private final StringBuilder myStringBuilder = new StringBuilder();
|
||||
|
||||
@Override
|
||||
protected void add(String s) {
|
||||
myStringBuilder.append(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addType(String name) {
|
||||
add(name);
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return myStringBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TypeToBodyWithLinksVisitor extends TypeNameVisitor {
|
||||
private ChainIterable<String> myBody;
|
||||
private PsiElement myAnchor;
|
||||
|
||||
public TypeToBodyWithLinksVisitor(ChainIterable<String> body, PsiElement anchor) {
|
||||
myBody = body;
|
||||
myAnchor = anchor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void add(String s) {
|
||||
myBody.addItem(combUp(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addType(String name) {
|
||||
PyType type = PyTypeParser.getTypeByName(myAnchor, name);
|
||||
if (type instanceof PyClassType) {
|
||||
myBody.addWith(new LinkWrapper(LINK_TYPE_TYPENAME + name),
|
||||
$(name));
|
||||
}
|
||||
else {
|
||||
add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class TypeNameVisitor implements TypeVisitor {
|
||||
@Override
|
||||
public void oneOf(OneOf oneOf) {
|
||||
add("one of (");
|
||||
boolean first = true;
|
||||
for (Type t : oneOf.oneOfTypes) {
|
||||
if (!first) {
|
||||
add(", ");
|
||||
}
|
||||
else {
|
||||
first = false;
|
||||
}
|
||||
|
||||
t.accept(this);
|
||||
}
|
||||
add(")");
|
||||
}
|
||||
|
||||
protected abstract void add(String s);
|
||||
|
||||
@Override
|
||||
public void collectionOf(CollectionOf collectionOf) {
|
||||
addType(collectionOf.collectionName);
|
||||
add(" of ");
|
||||
collectionOf.elementType.accept(this);
|
||||
}
|
||||
|
||||
protected abstract void addType(String name);
|
||||
|
||||
@Override
|
||||
public void name(String name) {
|
||||
addType(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ChainIterable<String> describeDecorators(PyDecoratable what, FP.Lambda1<Iterable<String>, Iterable<String>> deco_name_wrapper,
|
||||
String deco_separator, FP.Lambda1<String, String> escaper) {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
def foo(arg)
|
||||
Inferred type: (arg: unknown) -> int
|
||||
Inferred type: (arg: unknown) -> <a href="psi_element://#typename#int">int</a><br>
|
||||
@@ -1,3 +1,3 @@
|
||||
class A
|
||||
def f(self)
|
||||
Inferred type: (self: A) -> int
|
||||
Inferred type: (self: <a href="psi_element://#typename#A">A</a>) -> <a href="psi_element://#typename#int">int</a><br>
|
||||
@@ -1 +1 @@
|
||||
<html><body><code><small>class <a href="psi_element://#class#">B</a>(<a href="psi_element://#parent#A">A</a>)</small><br><br>def <b>foo</b>(self)<br>Inferred type: (self: B) -> None<br></code><br><br><i>Documentation is missing.</i> The following is copied from <code><a href="psi_element://#parent#A">A</a>.foo</code>.<br><br><code>Doc from A.foo.</code></body></html>
|
||||
<html><body><code><small>class <a href="psi_element://#class#">B</a>(<a href="psi_element://#parent#A">A</a>)</small><br><br>def <b>foo</b>(self)<br>Inferred type: (self: <a href="psi_element://#typename#B">B</a>) -> None<br></code><br><br><i>Documentation is missing.</i> The following is copied from <code><a href="psi_element://#parent#A">A</a>.foo</code>.<br><br><code>Doc from A.foo.</code></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body><code><small>class <a href="psi_element://#class#">Foo</a></small><br><br>@<i>deco</i><br>def <b>meth</b>(self)<br>Inferred type: (self: Foo) -> None<br><br><br>Doc of meth.<br></code></body></html>
|
||||
<html><body><code><small>class <a href="psi_element://#class#">Foo</a></small><br><br>@<i>deco</i><br>def <b>meth</b>(self)<br>Inferred type: (self: <a href="psi_element://#typename#Foo">Foo</a>) -> None<br><br><br>Doc of meth.<br></code></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<br><i>Copied from getter:</i><br>Does things to X<code><br><br>@<i>x.deleter</i><br>def <b>x</b>(self, v)<br>Inferred type: (self: A, v: unknown) -> None<br><br>Deletes X</code><small><br><br>Deleter of property</small><br></body></html>
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<br><i>Copied from getter:</i><br>Does things to X<code><br><br>@<i>x.deleter</i><br>def <b>x</b>(self, v)<br>Inferred type: (self: <a href="psi_element://#typename#A">A</a>, v: unknown) -> None<br><br>Deletes X</code><small><br><br>Deleter of property</small><br></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<code><br><br>@<i>property</i><br>def <b>x</b>(self)<br>Inferred type: (self: A) -> int<br><br>Does things to X</code><small><br><br>Getter of property</small><br></body></html>
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<code><br><br>@<i>property</i><br>def <b>x</b>(self)<br>Inferred type: (self: <a href="psi_element://#typename#A">A</a>) -> <a href="psi_element://#typename#int">int</a><br><br>Does things to X</code><small><br><br>Getter of property</small><br></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<br><i>Copied from getter:</i><br>Does things to X<code><br><br>@<i>x.setter</i><br>def <b>x</b>(self, v)<br>Inferred type: (self: A, v: unknown) -> None<br><br>Sets X</code><small><br><br>Setter of property</small><br></body></html>
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<br><i>Copied from getter:</i><br>Does things to X<code><br><br>@<i>x.setter</i><br>def <b>x</b>(self, v)<br>Inferred type: (self: <a href="psi_element://#typename#A">A</a>, v: unknown) -> None<br><br>Sets X</code><small><br><br>Setter of property</small><br></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<code><br><br>def <b>__getX</b>(self)<br>Inferred type: (self: A) -> unknown<br><br>Doc of getter</code><small><br><br>Deleter of property</small><br></body></html>
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<code><br><br>def <b>__getX</b>(self)<br>Inferred type: (self: <a href="psi_element://#typename#A">A</a>) -> unknown<br><br>Doc of getter</code><small><br><br>Deleter of property</small><br></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<code><br><br>def <b>__getX</b>(self)<br>Inferred type: (self: A) -> unknown<br><br>Doc of getter</code><small><br><br>Getter of property</small><br></body></html>
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<code><br><br>def <b>__getX</b>(self)<br>Inferred type: (self: <a href="psi_element://#typename#A">A</a>) -> unknown<br><br>Doc of getter</code><small><br><br>Getter of property</small><br></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<code><br><br>def <b>__getX</b>(self, x)<br>Inferred type: (self: A, x: unknown) -> None<br><br>Doc of getter</code><small><br><br>Setter of property</small><br></body></html>
|
||||
<html><body>property <b><code>x</code></b> of class <a href="psi_element://#class#">A</a>(<a href="psi_element://#parent#object">object</a>)<code><br><br>def <b>__getX</b>(self, x)<br>Inferred type: (self: <a href="psi_element://#typename#A">A</a>, x: unknown) -> None<br><br>Doc of getter</code><small><br><br>Setter of property</small><br></body></html>
|
||||
@@ -1 +1 @@
|
||||
<html><body><small>Assigned to <code>y</code><br></small><code><br>Inferred type: one of (<a href="psi_element://#typename#int">int</a>, <a href="psi_element://#typename#str">str</a>)</code></body></html>
|
||||
<html><body><small>Assigned to <code>y</code><br></small><code><br>Inferred type: one of (<a href="psi_element://#typename#int">int</a>, <a href="psi_element://#typename#str">str</a>)</code></body></html>
|
||||
Reference in New Issue
Block a user