mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
Fixed resolving '/' to __truediv__ when available (PY-5499, PY-4460)
This commit is contained in:
@@ -82,6 +82,8 @@ public class PyNames {
|
||||
public static final String DELITEM = "__delitem__";
|
||||
public static final String POS = "__pos__";
|
||||
public static final String NEG = "__neg__";
|
||||
public static final String DIV = "__div__";
|
||||
public static final String TRUEDIV = "__truediv__";
|
||||
|
||||
public static final String NAME = "__name__";
|
||||
public static final String ENTER = "__enter__";
|
||||
@@ -91,7 +93,7 @@ public class PyNames {
|
||||
public static final String COLLECTIONS_PY = "collections.py";
|
||||
|
||||
public static final String SET = "set";
|
||||
|
||||
|
||||
public static final String KEYS = "keys";
|
||||
|
||||
public static final String PASS = "pass";
|
||||
@@ -267,7 +269,7 @@ public class PyNames {
|
||||
// canonical names, not forced by interpreter
|
||||
public static final String CANONICAL_SELF = "self";
|
||||
public static final String BASESTRING = "basestring";
|
||||
|
||||
|
||||
/**
|
||||
* Contains keywords as of CPython 2.5.
|
||||
*/
|
||||
@@ -324,7 +326,7 @@ public class PyNames {
|
||||
* @return true iff name is not reserved and is a well-formed identifier.
|
||||
*/
|
||||
public static boolean isIdentifier(@NotNull @NonNls String name) {
|
||||
return ! isReserved(name) && IDENTIFIER_PATTERN.matcher(name).matches();
|
||||
return ! isReserved(name) && IDENTIFIER_PATTERN.matcher(name).matches();
|
||||
}
|
||||
|
||||
public static boolean isRightOperatorName(@Nullable String name) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.jetbrains.python.psi.impl.references;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
@@ -35,23 +36,10 @@ public class PyOperatorReference extends PyReferenceImpl {
|
||||
res = resolveMember(expr.getRightExpression(), name);
|
||||
}
|
||||
else {
|
||||
final TypeEvalContext typeEvalContext = myContext.getTypeEvalContext();
|
||||
typeEvalContext.trace("Trying to resolve left operator");
|
||||
typeEvalContext.traceIndent();
|
||||
try {
|
||||
res.addAll(resolveMember(expr.getLeftExpression(), name));
|
||||
}
|
||||
finally {
|
||||
typeEvalContext.traceUnindent();
|
||||
}
|
||||
typeEvalContext.trace("Trying to resolve right operator");
|
||||
typeEvalContext.traceIndent();
|
||||
try {
|
||||
res.addAll(resolveMember(expr.getRightExpression(), leftToRightOperatorName(name)));
|
||||
}
|
||||
finally {
|
||||
typeEvalContext.traceUnindent();
|
||||
if (PyNames.DIV.equals(name) && isTrueDivEnabled(myElement)) {
|
||||
resolveLeftAndRightOperators(res, expr, PyNames.TRUEDIV);
|
||||
}
|
||||
resolveLeftAndRightOperators(res, expr, name);
|
||||
}
|
||||
}
|
||||
else if (myElement instanceof PySubscriptionExpression) {
|
||||
@@ -92,6 +80,35 @@ public class PyOperatorReference extends PyReferenceImpl {
|
||||
return name.replaceFirst("__([a-z]+)__", "__r$1__");
|
||||
}
|
||||
|
||||
private static boolean isTrueDivEnabled(@NotNull PyElement anchor) {
|
||||
final PsiFile file = anchor.getContainingFile();
|
||||
if (file instanceof PyFile) {
|
||||
final PyFile pyFile = (PyFile)file;
|
||||
return FutureFeature.DIVISION.requiredAt(pyFile.getLanguageLevel()) || pyFile.hasImportFromFuture(FutureFeature.DIVISION);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void resolveLeftAndRightOperators(List<RatedResolveResult> res, PyBinaryExpression expr, String name) {
|
||||
final TypeEvalContext typeEvalContext = myContext.getTypeEvalContext();
|
||||
typeEvalContext.trace("Trying to resolve left operator");
|
||||
typeEvalContext.traceIndent();
|
||||
try {
|
||||
res.addAll(resolveMember(expr.getLeftExpression(), name));
|
||||
}
|
||||
finally {
|
||||
typeEvalContext.traceUnindent();
|
||||
}
|
||||
typeEvalContext.trace("Trying to resolve right operator");
|
||||
typeEvalContext.traceIndent();
|
||||
try {
|
||||
res.addAll(resolveMember(expr.getRightExpression(), leftToRightOperatorName(name)));
|
||||
}
|
||||
finally {
|
||||
typeEvalContext.traceUnindent();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<RatedResolveResult> resolveMember(@Nullable PyExpression object, @Nullable String name) {
|
||||
final ArrayList<RatedResolveResult> results = new ArrayList<RatedResolveResult>();
|
||||
|
||||
3
python/testData/resolve/TrueDiv.py
Normal file
3
python/testData/resolve/TrueDiv.py
Normal file
@@ -0,0 +1,3 @@
|
||||
def test(x):
|
||||
return 1 / x
|
||||
# <ref>
|
||||
@@ -40,4 +40,9 @@ public class Py3ResolveTest extends PyResolveTestCase {
|
||||
public void testObjectMethods() { // PY-1494
|
||||
assertResolvesTo(PyFunction.class, "__repr__");
|
||||
}
|
||||
|
||||
// PY-5499
|
||||
public void testTrueDiv() {
|
||||
assertResolvesTo(PyFunction.class, "__truediv__");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user