mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -12,7 +12,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public interface PyTargetExpression extends PyQualifiedExpression, PsiNamedElement, PsiNameIdentifierOwner, StubBasedPsiElement<PyTargetExpressionStub> {
|
||||
public interface PyTargetExpression extends PyQualifiedExpression, PsiNamedElement, PsiNameIdentifierOwner, PyDocStringOwner,
|
||||
StubBasedPsiElement<PyTargetExpressionStub> {
|
||||
PyTargetExpression[] EMPTY_ARRAY = new PyTargetExpression[0];
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,4 +45,7 @@ public interface PyTargetExpressionStub extends NamedStub<PyTargetExpression> {
|
||||
|
||||
@Nullable
|
||||
<T extends CustomTargetExpressionStub> T getCustomStub(Class<T> stubClass);
|
||||
|
||||
@Nullable
|
||||
String getDocString();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.jetbrains.python.documentation;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
@@ -19,12 +17,6 @@ public class DocStringUtil {
|
||||
private DocStringUtil() {
|
||||
}
|
||||
|
||||
public static String trimDocString(String s) {
|
||||
return s.trim()
|
||||
.replaceFirst("^((:py)?:class:`[~!]?|[A-Z]\\{)", "")
|
||||
.replaceFirst("(`|\\})?\\.?$", "");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getDocStringValue(@NotNull PyDocStringOwner owner) {
|
||||
return PyPsiUtils.strValue(owner.getDocStringExpression());
|
||||
@@ -81,24 +73,6 @@ public class DocStringUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyStringLiteralExpression getAttributeDocString(@NotNull PyTargetExpression attr) {
|
||||
if (attr.getParent() instanceof PyAssignmentStatement) {
|
||||
final PyAssignmentStatement assignment = (PyAssignmentStatement)attr.getParent();
|
||||
PsiElement nextSibling = assignment.getNextSibling();
|
||||
while (nextSibling != null && (nextSibling instanceof PsiWhiteSpace || nextSibling instanceof PsiComment)) {
|
||||
nextSibling = nextSibling.getNextSibling();
|
||||
}
|
||||
if (nextSibling instanceof PyExpressionStatement) {
|
||||
final PyExpression expression = ((PyExpressionStatement)nextSibling).getExpression();
|
||||
if (expression instanceof PyStringLiteralExpression) {
|
||||
return (PyStringLiteralExpression)expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getAttributeDocComment(@NotNull PyTargetExpression attr) {
|
||||
if (attr.getParent() instanceof PyAssignmentStatement) {
|
||||
@@ -115,31 +89,26 @@ public class DocStringUtil {
|
||||
}
|
||||
|
||||
public static boolean isVariableDocString(@NotNull PyStringLiteralExpression expr) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(expr);
|
||||
if (module == null) return false;
|
||||
final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(module);
|
||||
if (settings.isEpydocFormat(expr.getContainingFile()) || settings.isReSTFormat(expr.getContainingFile())) {
|
||||
final PsiElement parent = expr.getParent();
|
||||
if (!(parent instanceof PyExpressionStatement)) {
|
||||
return false;
|
||||
}
|
||||
PsiElement prevElement = parent.getPrevSibling();
|
||||
while (prevElement instanceof PsiWhiteSpace || prevElement instanceof PsiComment) {
|
||||
prevElement = prevElement.getPrevSibling();
|
||||
}
|
||||
if (prevElement instanceof PyAssignmentStatement) {
|
||||
if (expr.getText().contains("type:")) return true;
|
||||
final PsiElement parent = expr.getParent();
|
||||
if (!(parent instanceof PyExpressionStatement)) {
|
||||
return false;
|
||||
}
|
||||
PsiElement prevElement = parent.getPrevSibling();
|
||||
while (prevElement instanceof PsiWhiteSpace || prevElement instanceof PsiComment) {
|
||||
prevElement = prevElement.getPrevSibling();
|
||||
}
|
||||
if (prevElement instanceof PyAssignmentStatement) {
|
||||
if (expr.getText().contains("type:")) return true;
|
||||
|
||||
final PyAssignmentStatement assignmentStatement = (PyAssignmentStatement)prevElement;
|
||||
final ScopeOwner scope = PsiTreeUtil.getParentOfType(prevElement, ScopeOwner.class);
|
||||
if (scope instanceof PyClass || scope instanceof PyFile) {
|
||||
return true;
|
||||
}
|
||||
if (scope instanceof PyFunction) {
|
||||
for (PyExpression target : assignmentStatement.getTargets()) {
|
||||
if (PyUtil.isInstanceAttribute(target)) {
|
||||
return true;
|
||||
}
|
||||
final PyAssignmentStatement assignmentStatement = (PyAssignmentStatement)prevElement;
|
||||
final ScopeOwner scope = PsiTreeUtil.getParentOfType(prevElement, ScopeOwner.class);
|
||||
if (scope instanceof PyClass || scope instanceof PyFile) {
|
||||
return true;
|
||||
}
|
||||
if (scope instanceof PyFunction) {
|
||||
for (PyExpression target : assignmentStatement.getTargets()) {
|
||||
if (PyUtil.isInstanceAttribute(target)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.console.PyConsoleUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
@@ -229,9 +228,7 @@ class PyDocumentationBuilder {
|
||||
}
|
||||
|
||||
private boolean isAttribute() {
|
||||
return myElement instanceof PyTargetExpression &&
|
||||
(PyUtil.isInstanceAttribute((PyTargetExpression)myElement) ||
|
||||
PsiTreeUtil.getParentOfType(myElement, ScopeOwner.class) instanceof PyClass);
|
||||
return myElement instanceof PyTargetExpression && PyUtil.isAttribute((PyTargetExpression)myElement);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -449,7 +446,7 @@ class PyDocumentationBuilder {
|
||||
.addItem(" of class ").addWith(PythonDocumentationProvider.LinkMyClass, $().addWith(TagCode, $(cls.getName()))).addItem(BR)
|
||||
;
|
||||
|
||||
final String docString = PyPsiUtils.strValue(DocStringUtil.getAttributeDocString((PyTargetExpression)myElement));
|
||||
final String docString = ((PyTargetExpression)myElement).getDocStringValue();
|
||||
if (docString != null) {
|
||||
addFormattedDocString(myElement, docString, myBody, myEpilog);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ public class PyFileElementType extends IStubFileElementType<PyFileStub> {
|
||||
|
||||
@Override
|
||||
public int getStubVersion() {
|
||||
return 47;
|
||||
// Don't forget to update versions of indexes that use the updated stub-based elements
|
||||
return 48;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -435,6 +435,10 @@ public class PyUtil {
|
||||
if (!thing) throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
public static boolean isAttribute(PyTargetExpression ex) {
|
||||
return isInstanceAttribute(ex) || isClassAttribute(ex);
|
||||
}
|
||||
|
||||
public static boolean isInstanceAttribute(PyExpression target) {
|
||||
if (!(target instanceof PyTargetExpression)) {
|
||||
return false;
|
||||
@@ -443,6 +447,9 @@ public class PyUtil {
|
||||
if (owner instanceof PyFunction) {
|
||||
final PyFunction method = (PyFunction)owner;
|
||||
if (method.getContainingClass() != null) {
|
||||
if (method.getStub() != null) {
|
||||
return true;
|
||||
}
|
||||
final PyParameter[] params = method.getParameterList().getParameters();
|
||||
if (params.length > 0) {
|
||||
final PyTargetExpression targetExpr = (PyTargetExpression)target;
|
||||
|
||||
@@ -926,9 +926,8 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
|
||||
if (params.length == 0) {
|
||||
return;
|
||||
}
|
||||
final PyFunctionStub methodStub = method.getStub();
|
||||
for (PyTargetExpression target : getTargetExpressions(method)) {
|
||||
if (methodStub != null || PyUtil.isInstanceAttribute(target)) {
|
||||
if (PyUtil.isInstanceAttribute(target)) {
|
||||
result.put(target.getName(), target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
@@ -25,7 +22,6 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.Scope;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.StructuredDocString;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.references.PyQualifiedReference;
|
||||
import com.jetbrains.python.psi.impl.references.PyTargetReference;
|
||||
@@ -120,10 +116,14 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
if (pyType != null) {
|
||||
return pyType;
|
||||
}
|
||||
PyType type = getTypeFromDocString();
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
if (!context.maySwitchToAST(this)) {
|
||||
final PsiElement value = getStub() != null ? findAssignedValueByStub(context) : findAssignedValue();
|
||||
if (value instanceof PyTypedElement) {
|
||||
final PyType type = context.getType((PyTypedElement)value);
|
||||
type = context.getType((PyTypedElement)value);
|
||||
if (type instanceof PyNoneType) {
|
||||
return null;
|
||||
}
|
||||
@@ -135,10 +135,6 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
}
|
||||
return null;
|
||||
}
|
||||
PyType type = getTypeFromDocString(this);
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
type = getTypeFromComment(this);
|
||||
if (type != null) {
|
||||
return type;
|
||||
@@ -249,20 +245,28 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyType getTypeFromDocString(PyTargetExpressionImpl targetExpression) {
|
||||
final String docString = PyPsiUtils.strValue(DocStringUtil.getAttributeDocString(targetExpression));
|
||||
if (docString != null) {
|
||||
StructuredDocString structuredDocString = DocStringUtil.parse(docString);
|
||||
if (structuredDocString != null) {
|
||||
String typeName = structuredDocString.getParamType(null);
|
||||
if (typeName == null) {
|
||||
typeName = structuredDocString.getParamType(targetExpression.getName());
|
||||
}
|
||||
if (typeName != null) {
|
||||
return PyTypeParser.getTypeByName(targetExpression, typeName);
|
||||
private PyType getTypeFromDocString() {
|
||||
String typeName = null;
|
||||
final String name = getName();
|
||||
final StructuredDocString targetDocString = getStructuredDocString();
|
||||
if (targetDocString != null) {
|
||||
typeName = targetDocString.getParamType(null);
|
||||
if (typeName == null) {
|
||||
typeName = targetDocString.getParamType(name);
|
||||
}
|
||||
}
|
||||
if (typeName == null && PyUtil.isAttribute(this)) {
|
||||
final PyClass cls = getContainingClass();
|
||||
if (cls != null) {
|
||||
final StructuredDocString classDocString = cls.getStructuredDocString();
|
||||
if (classDocString != null) {
|
||||
typeName = classDocString.getParamType(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeName != null) {
|
||||
return PyTypeParser.getTypeByName(this, typeName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -603,4 +607,40 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
}
|
||||
return super.getElementLocation();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getDocStringValue() {
|
||||
final PyTargetExpressionStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getDocString();
|
||||
}
|
||||
return DocStringUtil.getDocStringValue(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StructuredDocString getStructuredDocString() {
|
||||
return DocStringUtil.getStructuredDocString(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyStringLiteralExpression getDocStringExpression() {
|
||||
final PsiElement parent = getParent();
|
||||
if (parent instanceof PyAssignmentStatement) {
|
||||
final PyAssignmentStatement assignment = (PyAssignmentStatement)parent;
|
||||
PsiElement nextSibling = assignment.getNextSibling();
|
||||
while (nextSibling != null && (nextSibling instanceof PsiWhiteSpace || nextSibling instanceof PsiComment)) {
|
||||
nextSibling = nextSibling.getNextSibling();
|
||||
}
|
||||
if (nextSibling instanceof PyExpressionStatement) {
|
||||
final PyExpression expression = ((PyExpressionStatement)nextSibling).getExpression();
|
||||
if (expression instanceof PyStringLiteralExpression) {
|
||||
return (PyStringLiteralExpression)expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,8 +429,8 @@ public class PyQualifiedReference extends PyReferenceImpl {
|
||||
if (resolveResult == element) {
|
||||
return true;
|
||||
}
|
||||
if (resolveResult instanceof PyTargetExpression && isInstanceOrClassAttribute((PyTargetExpression)resolveResult) &&
|
||||
element instanceof PyTargetExpression && isInstanceOrClassAttribute((PyTargetExpression)element) && Comparing.equal(
|
||||
if (resolveResult instanceof PyTargetExpression && PyUtil.isAttribute((PyTargetExpression)resolveResult) &&
|
||||
element instanceof PyTargetExpression && PyUtil.isAttribute((PyTargetExpression)element) && Comparing.equal(
|
||||
((PyTargetExpression)resolveResult).getReferencedName(),
|
||||
((PyTargetExpression)element).getReferencedName())) {
|
||||
PyClass aClass = PsiTreeUtil.getParentOfType(resolveResult, PyClass.class);
|
||||
@@ -448,10 +448,6 @@ public class PyQualifiedReference extends PyReferenceImpl {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isInstanceOrClassAttribute(PyTargetExpression ex) {
|
||||
return PyUtil.isInstanceAttribute(ex) || PyUtil.isClassAttribute(ex);
|
||||
}
|
||||
|
||||
private static boolean isSubclass(@Nullable PyClass aClass, @Nullable PyClass bClass) {
|
||||
if (aClass == null || bClass == null) {
|
||||
return false;
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.io.StringRef;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.documentation.DocStringUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyQualifiedName;
|
||||
import com.jetbrains.python.psi.impl.PyTargetExpressionImpl;
|
||||
@@ -48,10 +49,11 @@ public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExp
|
||||
public PyTargetExpressionStub createStub(@NotNull final PyTargetExpression psi, final StubElement parentStub) {
|
||||
final String name = psi.getName();
|
||||
final PyExpression assignedValue = psi.findAssignedValue();
|
||||
final String docString = DocStringUtil.getDocStringValue(psi);
|
||||
for (CustomTargetExpressionStubType customStubType : getCustomStubTypes()) {
|
||||
CustomTargetExpressionStub customStub = customStubType.createStub(psi);
|
||||
if (customStub != null) {
|
||||
return new PyTargetExpressionStubImpl(name, customStub, parentStub);
|
||||
return new PyTargetExpressionStubImpl(name, docString, customStub, parentStub);
|
||||
}
|
||||
}
|
||||
PyTargetExpressionStub.InitializerType initializerType = PyTargetExpressionStub.InitializerType.Other;
|
||||
@@ -67,12 +69,14 @@ public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExp
|
||||
initializer = ((PyReferenceExpression) callee).asQualifiedName();
|
||||
}
|
||||
}
|
||||
return new PyTargetExpressionStubImpl(name, initializerType, initializer, psi.getQualifier() != null, parentStub);
|
||||
return new PyTargetExpressionStubImpl(name, docString, initializerType, initializer, psi.getQualifier() != null, parentStub);
|
||||
}
|
||||
|
||||
public void serialize(@NotNull final PyTargetExpressionStub stub, @NotNull final StubOutputStream stream)
|
||||
throws IOException {
|
||||
stream.writeName(stub.getName());
|
||||
final String docString = stub.getDocString();
|
||||
stream.writeUTFFast(docString != null ? docString : "");
|
||||
stream.writeVarInt(stub.getInitializerType().getIndex());
|
||||
final CustomTargetExpressionStub customStub = stub.getCustomStub(CustomTargetExpressionStub.class);
|
||||
if (customStub != null) {
|
||||
@@ -89,20 +93,24 @@ public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExp
|
||||
public PyTargetExpressionStub deserialize(@NotNull final StubInputStream stream, final StubElement parentStub)
|
||||
throws IOException {
|
||||
String name = StringRef.toString(stream.readName());
|
||||
String docString = stream.readUTFFast();
|
||||
if (docString.isEmpty()) {
|
||||
docString = null;
|
||||
}
|
||||
PyTargetExpressionStub.InitializerType initializerType = PyTargetExpressionStub.InitializerType.fromIndex(stream.readVarInt());
|
||||
if (initializerType == PyTargetExpressionStub.InitializerType.Custom) {
|
||||
final String typeName = stream.readName().getString();
|
||||
for(CustomTargetExpressionStubType type: getCustomStubTypes()) {
|
||||
if (type.getClass().getCanonicalName().equals(typeName)) {
|
||||
CustomTargetExpressionStub stub = type.deserializeStub(stream);
|
||||
return new PyTargetExpressionStubImpl(name, stub, parentStub);
|
||||
return new PyTargetExpressionStubImpl(name, docString, stub, parentStub);
|
||||
}
|
||||
}
|
||||
throw new IOException("Unknown custom stub type " + typeName);
|
||||
}
|
||||
PyQualifiedName initializer = PyQualifiedName.deserialize(stream);
|
||||
boolean isQualified = stream.readBoolean();
|
||||
return new PyTargetExpressionStubImpl(name, initializerType, initializer, isQualified, parentStub);
|
||||
return new PyTargetExpressionStubImpl(name, docString, initializerType, initializer, isQualified, parentStub);
|
||||
}
|
||||
|
||||
public boolean shouldCreateStub(final ASTNode node) {
|
||||
|
||||
@@ -16,19 +16,24 @@ public class PyTargetExpressionStubImpl extends StubBase<PyTargetExpression> imp
|
||||
private final InitializerType myInitializerType;
|
||||
private final PyQualifiedName myInitializer;
|
||||
private final boolean myQualified;
|
||||
@Nullable private final String myDocString;
|
||||
|
||||
private final CustomTargetExpressionStub myCustomStub;
|
||||
|
||||
public PyTargetExpressionStubImpl(String name, CustomTargetExpressionStub customStub, StubElement parent) {
|
||||
public PyTargetExpressionStubImpl(String name,
|
||||
@Nullable String docString,
|
||||
CustomTargetExpressionStub customStub,
|
||||
StubElement parent) {
|
||||
super(parent, PyElementTypes.TARGET_EXPRESSION);
|
||||
myName = name;
|
||||
myInitializerType = InitializerType.Custom;
|
||||
myInitializer = null;
|
||||
myQualified = false;
|
||||
myCustomStub = customStub;
|
||||
myDocString = docString;
|
||||
}
|
||||
|
||||
public PyTargetExpressionStubImpl(final String name, final InitializerType initializerType,
|
||||
public PyTargetExpressionStubImpl(final String name, @Nullable String docString, final InitializerType initializerType,
|
||||
final PyQualifiedName initializer,
|
||||
final boolean qualified,
|
||||
final StubElement parentStub) {
|
||||
@@ -39,6 +44,7 @@ public class PyTargetExpressionStubImpl extends StubBase<PyTargetExpression> imp
|
||||
myInitializer = initializer;
|
||||
myQualified = qualified;
|
||||
myCustomStub = null;
|
||||
myDocString = docString;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -67,6 +73,12 @@ public class PyTargetExpressionStubImpl extends StubBase<PyTargetExpression> imp
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getDocString() {
|
||||
return myDocString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PyTargetExpressionStub(name=" + myName + ")";
|
||||
|
||||
@@ -16,6 +16,11 @@ import java.util.Collection;
|
||||
public class PyInstanceAttributeIndex extends StringStubIndexExtension<PyTargetExpression> {
|
||||
public static final StubIndexKey<String, PyTargetExpression> KEY = StubIndexKey.createIndexKey("Py.instanceAttribute.name");
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return super.getVersion() + 1;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StubIndexKey<String, PyTargetExpression> getKey() {
|
||||
|
||||
@@ -16,6 +16,11 @@ import java.util.Collection;
|
||||
public class PyVariableNameIndex extends StringStubIndexExtension<PyTargetExpression> {
|
||||
public static final StubIndexKey<String, PyTargetExpression> KEY = StubIndexKey.createIndexKey("Py.variable.shortName");
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return super.getVersion() + 1;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StubIndexKey<String, PyTargetExpression> getKey() {
|
||||
return KEY;
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.jetbrains.python.refactoring.introduce.parameter.PyIntroduceParameter
|
||||
import com.jetbrains.python.refactoring.introduce.constant.PyIntroduceConstantHandler;
|
||||
import com.jetbrains.python.refactoring.introduce.field.PyIntroduceFieldHandler;
|
||||
import com.jetbrains.python.refactoring.introduce.variable.PyIntroduceVariableHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -59,7 +60,7 @@ public class PyRefactoringProvider extends RefactoringSupportProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) {
|
||||
public boolean isInplaceRenameAvailable(@NotNull PsiElement element, PsiElement context) {
|
||||
if (context != null && context.getContainingFile() != element.getContainingFile()) return false;
|
||||
PyFunction containingFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class);
|
||||
if (containingFunction != null) {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
class GetCustomerPaymentProfileRequest(CustomerRequest):
|
||||
_keys = CustomerRequest._keys + ["customerPaymentProfileId"]
|
||||
def __init__(self, user, profileid):
|
||||
CustomerRequest.__init__(self, user,
|
||||
customerPaymentProfileId=profileid)
|
||||
<warning descr="Docstring seems to be misplaced">"""
|
||||
Gets a payment profile by user <caret>Account object and authorize.net
|
||||
profileid of the payment profile.
|
||||
"""</warning>
|
||||
def __init__(self, user, profileid):
|
||||
CustomerRequest.__init__(self, user,
|
||||
customerPaymentProfileId=profileid)
|
||||
@@ -3,8 +3,7 @@ class GetCustomerPaymentProfileRequest(CustomerRequest):
|
||||
Gets a payment profile by user Account object and authorize.net
|
||||
profileid of the payment profile.
|
||||
"""
|
||||
_keys = CustomerRequest._keys + ["customerPaymentProfileId"]
|
||||
|
||||
def __init__(self, user, profileid):
|
||||
CustomerRequest.__init__(self, user,
|
||||
customerPaymentProfileId=profileid)
|
||||
customerPaymentProfileId=profileid)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class C(object):
|
||||
foo = None
|
||||
"""Foo docstring."""
|
||||
|
||||
bar = None
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.jetbrains.python;
|
||||
import com.intellij.codeInsight.controlflow.ControlFlow;
|
||||
import com.intellij.codeInsight.controlflow.Instruction;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
@@ -14,7 +13,6 @@ import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@@ -234,7 +232,7 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
|
||||
for (Instruction instruction : instructions) {
|
||||
buffer.append(instruction).append("\n");
|
||||
}
|
||||
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
|
||||
final VirtualFile vFile = getVirtualFileByName(fullPath);
|
||||
try {
|
||||
final String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile), "\n");
|
||||
assertEquals(fileText.trim(), buffer.toString().trim());
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -11,7 +10,6 @@ import com.jetbrains.python.fixtures.LightMarkedTestCase;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -35,7 +33,7 @@ public class PyQuickDocTest extends LightMarkedTestCase {
|
||||
|
||||
private void checkByHTML(String text, @TestDataFile String filePath) {
|
||||
final String fullPath = getTestDataPath() + filePath;
|
||||
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
|
||||
final VirtualFile vFile = getVirtualFileByName(fullPath);
|
||||
assertNotNull("file " + fullPath + " not found", vFile);
|
||||
|
||||
String loadedText;
|
||||
|
||||
@@ -402,6 +402,14 @@ public class PyStubsTest extends PyTestCase {
|
||||
}
|
||||
classes = PyClassNameIndex.find("Foo", project, GlobalSearchScope.allScope(project));
|
||||
assertEquals(classes.size(), 1);
|
||||
}
|
||||
|
||||
public void testTargetExpressionDocString() {
|
||||
final PyFile file = getTestFile();
|
||||
final PyClass c = file.findTopLevelClass("C");
|
||||
assertNotNull(c);
|
||||
final PyTargetExpression foo = c.findClassAttribute("foo", false);
|
||||
final String docString = foo.getDocStringValue();
|
||||
assertEquals("Foo docstring.", docString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,6 +646,44 @@ public class PyTypeTest extends PyTestCase {
|
||||
"expr = func(foo)\n");
|
||||
}
|
||||
|
||||
// PY-6584
|
||||
public void testClassAttributeTypeInClassDocStringViaClass() {
|
||||
doTest("int",
|
||||
"class C(object):\n" +
|
||||
" '''\n" +
|
||||
" :type foo: int\n" +
|
||||
" '''\n" +
|
||||
" foo = None\n" +
|
||||
"\n" +
|
||||
"expr = C.foo\n");
|
||||
}
|
||||
|
||||
// PY-6584
|
||||
public void testClassAttributeTypeInClassDocStringViaInstance() {
|
||||
doTest("int",
|
||||
"class C(object):\n" +
|
||||
" '''\n" +
|
||||
" :type foo: int\n" +
|
||||
" '''\n" +
|
||||
" foo = None\n" +
|
||||
"\n" +
|
||||
"expr = C().foo\n");
|
||||
}
|
||||
|
||||
// PY-6584
|
||||
public void testInstanceAttributeTypeInClassDocString() {
|
||||
doTest("int",
|
||||
"class C(object):\n" +
|
||||
" '''\n" +
|
||||
" :type foo: int\n" +
|
||||
" '''\n" +
|
||||
" def __init__(self, bar):\n" +
|
||||
" self.foo = bar\n" +
|
||||
"\n" +
|
||||
"def f(x):\n" +
|
||||
" expr = C(x).foo\n");
|
||||
}
|
||||
|
||||
private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) {
|
||||
return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing();
|
||||
}
|
||||
|
||||
@@ -140,15 +140,7 @@ public class PythonInspectionsTest extends PyTestCase {
|
||||
}
|
||||
|
||||
public void testPyStatementEffectInspection() {
|
||||
final PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule());
|
||||
final String oldFormat = documentationSettings.getFormat();
|
||||
try {
|
||||
documentationSettings.setFormat(DocStringFormat.EPYTEXT);
|
||||
doHighlightingTest(PyStatementEffectInspection.class, LanguageLevel.PYTHON26);
|
||||
}
|
||||
finally {
|
||||
documentationSettings.setFormat(oldFormat);
|
||||
}
|
||||
doHighlightingTest(PyStatementEffectInspection.class, LanguageLevel.PYTHON26);
|
||||
}
|
||||
|
||||
public void testPySimplifyBooleanCheckInspection() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.jetbrains.python.fixtures;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -10,7 +9,6 @@ import com.intellij.testFramework.TestDataFile;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -49,7 +47,7 @@ public abstract class LightMarkedTestCase extends PyTestCase {
|
||||
*/
|
||||
protected Map<String, PsiElement> configureByFile(@TestDataFile @NonNls String filePath, @NonNls String markerRegexp) {
|
||||
final String fullPath = getTestDataPath() + filePath;
|
||||
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
|
||||
final VirtualFile vFile = getVirtualFileByName(fullPath);
|
||||
assertNotNull("file " + fullPath + " not found", vFile);
|
||||
|
||||
final String text;
|
||||
|
||||
@@ -31,6 +31,8 @@ import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
@@ -46,6 +48,11 @@ public abstract class PyTestCase extends UsefulTestCase {
|
||||
protected CodeInsightTestFixture myFixture;
|
||||
private static boolean ourPlatformPrefixInitialized;
|
||||
|
||||
@Nullable
|
||||
protected static VirtualFile getVirtualFileByName(String fileName) {
|
||||
return LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/'));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.intellij.codeInsight.codeFragment.CannotCreateCodeFragmentException;
|
||||
import com.intellij.codeInsight.codeFragment.CodeFragment;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -15,7 +14,6 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.fixtures.LightMarkedTestCase;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
@@ -35,7 +33,7 @@ public class PyCodeFragmentTest extends LightMarkedTestCase {
|
||||
final String testName = getTestName(false).toLowerCase();
|
||||
final String fullPath = getTestDataPath() + testName + ".test";
|
||||
|
||||
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
|
||||
final VirtualFile vFile = getVirtualFileByName(fullPath);
|
||||
String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile), "\n");
|
||||
|
||||
final int beginMarker = fileText.indexOf(BEGIN_MARKER);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.jetbrains.python.refactoring;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
|
||||
@@ -16,7 +15,6 @@ import com.jetbrains.python.psi.stubs.PyFunctionNameIndex;
|
||||
import com.jetbrains.python.refactoring.move.PyMoveClassOrFunctionProcessor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -178,11 +176,6 @@ public class PyMoveTest extends PyTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static VirtualFile getVirtualFileByName(String fileName) {
|
||||
return LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/'));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiNamedElement findFirstNamedElement(String name) {
|
||||
final Collection<PyClass> classes = PyClassNameIndex.find(name, myFixture.getProject(), false);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.jetbrains.python.refactoring;
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -10,9 +9,7 @@ import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.jetbrains.python.PythonTestUtil;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@@ -197,7 +194,7 @@ public class PyRenameTest extends PyTestCase {
|
||||
PsiDocumentManager.getInstance(myFixture.getProject()).commitAllDocuments();
|
||||
myFixture.configureFromTempProjectFile("a.py");
|
||||
myFixture.renameElementAtCaret(newName);
|
||||
VirtualFile dir2 = getVirtualFileByName(PythonTestUtil.getTestDataPath() + "/" + RENAME_DATA_PATH + testName + "/after");
|
||||
VirtualFile dir2 = PyTestCase.getVirtualFileByName(PythonTestUtil.getTestDataPath() + "/" + RENAME_DATA_PATH + testName + "/after");
|
||||
try {
|
||||
PlatformTestUtil.assertDirectoriesEqual(dir2, dir1);
|
||||
}
|
||||
@@ -205,9 +202,4 @@ public class PyRenameTest extends PyTestCase {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static VirtualFile getVirtualFileByName(String fileName) {
|
||||
return LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user