mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 10:20:15 +07:00
[python] support Pathlib-style path declarations in PyPathEvaluator (PY-13911)
(cherry picked from commit 3673aa3bac948bae5c7e8fd6521f251285d70cf9) IJ-MR-17579 GitOrigin-RevId: 17d336d8f6d5e16bd3dca815c2f9935911e050ee
This commit is contained in:
committed by
intellij-monorepo-bot
parent
effa066a2d
commit
05a99b5e99
@@ -137,7 +137,7 @@ public class PyEvaluator {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object evaluateBinary(@NotNull PyBinaryExpression expression) {
|
||||
protected Object evaluateBinary(@NotNull PyBinaryExpression expression) {
|
||||
final PyElementType op = expression.getOperator();
|
||||
final Object lhs = evaluate(expression.getLeftExpression());
|
||||
final Object rhs = evaluate(expression.getRightExpression());
|
||||
|
||||
@@ -18,9 +18,8 @@ package com.jetbrains.python.psi.impl;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.psi.PyCallExpression;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyReferenceExpression;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -49,6 +48,15 @@ public class PyPathEvaluator extends PyEvaluator {
|
||||
@Nullable
|
||||
protected Object evaluateCall(@NotNull PyCallExpression expression) {
|
||||
final PyExpression[] args = expression.getArguments();
|
||||
if (expression.isCalleeText("resolve")) {
|
||||
PyReferenceExpression callee = (PyReferenceExpression)expression.getCallee();
|
||||
if (callee != null && callee.getQualifier() instanceof PyCallExpression) {
|
||||
return evaluate(callee.getQualifier());
|
||||
}
|
||||
}
|
||||
if (expression.isCalleeText("Path") && args.length >= 1) {
|
||||
return evaluate(args[0]);
|
||||
}
|
||||
if (expression.isCalleeText(PyNames.DIRNAME) && args.length == 1) {
|
||||
Object argValue = evaluate(args[0]);
|
||||
return argValue instanceof String ? Paths.get((String) argValue).getParent().toFile().getPath() : null;
|
||||
@@ -89,6 +97,12 @@ public class PyPathEvaluator extends PyEvaluator {
|
||||
if (!expression.isQualified() && PyNames.FILE.equals(expression.getReferencedName())) {
|
||||
return FileUtil.toSystemIndependentName(myContainingFilePath);
|
||||
}
|
||||
if ("parent".equals(expression.getName()) && expression.isQualified()) {
|
||||
Object qualifier = evaluate(expression.getQualifier());
|
||||
if (qualifier instanceof String) {
|
||||
return Paths.get((String)qualifier).getParent().toFile().getPath();
|
||||
}
|
||||
}
|
||||
return super.evaluateReference(expression);
|
||||
}
|
||||
|
||||
@@ -108,4 +122,17 @@ public class PyPathEvaluator extends PyEvaluator {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Object evaluateBinary(@NotNull PyBinaryExpression expression) {
|
||||
final PyElementType operator = expression.getOperator();
|
||||
if (operator == PyTokenTypes.DIV) {
|
||||
final Object lhs = evaluate(expression.getLeftExpression());
|
||||
final Object rhs = evaluate(expression.getRightExpression());
|
||||
if (lhs instanceof String && rhs instanceof String) {
|
||||
return FileUtil.toSystemIndependentName(Paths.get((String)lhs, (String)rhs).toFile().getPath());
|
||||
}
|
||||
}
|
||||
return super.evaluateBinary(expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,26 @@ public class PyPathEvaluatorTest extends PyTestCase {
|
||||
assertEquals("/foo/subfolder/../bar.py", doEvaluate("os.path.abspath(os.path.join(os.path.join('/foo/subfolder', os.path.pardir, 'bar.py')))", "/foo/bar.py"));
|
||||
}
|
||||
|
||||
// PY-13911
|
||||
public void testPathlibRoot() {
|
||||
assertEquals("/foo/bar/baz.py", doEvaluate("Path(__file__)", "/foo/bar/baz.py"));
|
||||
}
|
||||
|
||||
// PY-13911
|
||||
public void testPathlibParent() {
|
||||
assertEquals("/foo", doEvaluate("Path(__file__).resolve().parent.parent", "/foo/bar/baz.py"));
|
||||
}
|
||||
|
||||
// PY-13911
|
||||
public void testPathlibAbsolutePath() {
|
||||
assertEquals("/foo/bar", doEvaluate("Path('/foo/bar')", "/irrelevant"));
|
||||
}
|
||||
|
||||
// PY-13911
|
||||
public void testPathlibJoin() {
|
||||
assertEquals("/foo/bar/baz.py", doEvaluate("Path(__file__).resolve() / 'bar' / 'baz.py'", "/foo"));
|
||||
}
|
||||
|
||||
private String doEvaluate(final String text, final String file) {
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(myFixture.getProject());
|
||||
final PyExpression expression = generator.createExpressionFromText(LanguageLevel.getLatest(), text);
|
||||
|
||||
Reference in New Issue
Block a user