mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-12810 "imported" urls are not supported by {% url %} tag ( "patterns +=" now supported)
This commit is contained in:
@@ -61,6 +61,8 @@ public class NewDirectoryProjectDialog extends DialogWrapper {
|
||||
setTitle("Create New Project");
|
||||
init();
|
||||
|
||||
myLocationField = new TextFieldWithBrowseButton();
|
||||
myLocationLabel = new JLabel();
|
||||
myLocationLabel.setLabelFor(myLocationField.getChildComponent());
|
||||
|
||||
new LocationNameFieldsBinding(project, myLocationField, myProjectNameTextField, ProjectUtil.getBaseDir(), "Select Location for Project Directory");
|
||||
|
||||
@@ -62,7 +62,9 @@ public class PsiQuery {
|
||||
|
||||
|
||||
/**
|
||||
* TODO: Support types?
|
||||
* Filter children by function call
|
||||
* @return {@link com.jetbrains.python.psi.PsiQuery} backed by {@link com.jetbrains.python.psi.PyCallExpression}
|
||||
*/
|
||||
@NotNull
|
||||
public PsiQuery childrenCall(@NotNull final FQNamesProvider name) {
|
||||
|
||||
@@ -850,6 +850,29 @@ public class PyUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts collection to list of certain type
|
||||
* @param expression expression of collection type
|
||||
* @param elementClass expected element type
|
||||
* @param <T> expected element type
|
||||
* @return list of elements of expected element type
|
||||
*/
|
||||
@NotNull
|
||||
public static <T> List<T> asList(@Nullable final Collection<?> expression, @NotNull final Class<T> elementClass) {
|
||||
if ((expression == null) || expression.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<T> result = new ArrayList<T>();
|
||||
for (final Object element : expression) {
|
||||
final T toAdd = as(element, elementClass);
|
||||
if (toAdd != null) {
|
||||
result.add(toAdd);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class KnownDecoratorProviderHolder {
|
||||
public static PyKnownDecoratorProvider[] KNOWN_DECORATOR_PROVIDERS = Extensions.getExtensions(PyKnownDecoratorProvider.EP_NAME);
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Evaluator tht supports expression of any type (it evaluates any expression, concatenating several expressions to list etc)
|
||||
*/
|
||||
public class PyAnyExpressionEvaluator extends PyEvaluator {
|
||||
private final boolean myEvalSequence;
|
||||
|
||||
/**
|
||||
* @param evalSequence evaluate sequencies ((a,b) + (c,d) == (a,b,c,d)) or store them as single ((a,b) + (c,d) = [(a,b), (c,d)])
|
||||
*/
|
||||
public PyAnyExpressionEvaluator(final boolean evalSequence) {
|
||||
myEvalSequence = evalSequence;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object evaluate(final PyExpression expr) {
|
||||
final Object evaluate = super.evaluate(expr);
|
||||
return ((evaluate != null) ? evaluate : expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object concatenate(final Object lhs, final Object rhs) {
|
||||
final Object evaluate = super.concatenate(lhs, rhs);
|
||||
return ((evaluate != null) ? evaluate : Arrays.asList(lhs, rhs));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluateReferenceExpression(final PyReferenceExpression expr) {
|
||||
final Object evaluate = super.evaluateReferenceExpression(expr);
|
||||
return ((evaluate != null) ? evaluate : expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluateCall(final PyCallExpression call) {
|
||||
final Object evaluate = super.evaluateCall(call);
|
||||
return ((evaluate != null) ? evaluate : call);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluateSequenceExpression(final PySequenceExpression expr) {
|
||||
return myEvalSequence ? super.evaluateSequenceExpression(expr) : expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates expression to single element
|
||||
* @param expression exp to eval
|
||||
* @param aClass expected class
|
||||
* @param <T> expected class
|
||||
* @return instance of aClass, or null if failed to eval
|
||||
*/
|
||||
@Nullable
|
||||
public static <T> T evaluateOne(@NotNull final PyExpression expression, @NotNull final Class<T> aClass) {
|
||||
final PyAnyExpressionEvaluator evaluator = new PyAnyExpressionEvaluator(false);
|
||||
final Object evaluate = evaluator.evaluate(expression);
|
||||
final T resultSingle = PyUtil.as(evaluate, aClass);
|
||||
if (resultSingle != null) {
|
||||
return resultSingle;
|
||||
}
|
||||
final List<?> resultMultiple = PyUtil.as(evaluate, List.class);
|
||||
if ((resultMultiple != null) && !resultMultiple.isEmpty()) {
|
||||
return PyUtil.as(resultMultiple.get(0), aClass);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluates expression to string
|
||||
* @param expression exp to eval
|
||||
* @return string, or null if failed to eval
|
||||
*/
|
||||
@Nullable
|
||||
public static String evaluateString(@NotNull final PyExpression expression) {
|
||||
return PyUtil.as(new PyAnyExpressionEvaluator(false).evaluate(expression), String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates expression as list of values
|
||||
* @param expression exp to eval
|
||||
* @param aClass expected element class
|
||||
* @param <T> expected element class
|
||||
* @return a list of elements of expected type
|
||||
*/
|
||||
@NotNull
|
||||
public static <T>List<T> evaluateIterable(@NotNull final PyExpression expression, @NotNull final Class<T> aClass) {
|
||||
final PyAnyExpressionEvaluator evaluator = new PyAnyExpressionEvaluator(true);
|
||||
final Object evaluate = evaluator.evaluate(expression);
|
||||
final T resultSingle = PyUtil.as(evaluate, aClass);
|
||||
if (resultSingle != null) {
|
||||
return Collections.singletonList(resultSingle);
|
||||
}
|
||||
return PyUtil.asList(PyUtil.as(evaluate, List.class), aClass);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see {@link com.jetbrains.python.psi.impl.PyExpressionEvaluator} (TODO: merge both classes?)
|
||||
* @author yole
|
||||
*/
|
||||
public class PyBlockEvaluator {
|
||||
@@ -99,7 +98,7 @@ public class PyBlockEvaluator {
|
||||
Object currentValue = myNamespace.get(name);
|
||||
if (currentValue != null) {
|
||||
Object rhs = prepareEvaluator().evaluate(node.getValue());
|
||||
myNamespace.put(name, PyEvaluator.concatenate(currentValue, rhs));
|
||||
myNamespace.put(name, prepareEvaluator().concatenate(currentValue, rhs));
|
||||
}
|
||||
if (myDeclarationsToTrack.contains(name)) {
|
||||
List<PyExpression> declarations = myDeclarations.get(name);
|
||||
@@ -189,7 +188,7 @@ public class PyBlockEvaluator {
|
||||
Object value = myNamespace.get(nameBeingExtended);
|
||||
if (value instanceof List) {
|
||||
Object argValue = prepareEvaluator().evaluate(arg);
|
||||
myNamespace.put(nameBeingExtended, PyEvaluator.concatenate(value, argValue));
|
||||
myNamespace.put(nameBeingExtended, prepareEvaluator().concatenate(value, argValue));
|
||||
}
|
||||
|
||||
if (myDeclarationsToTrack.contains(nameBeingExtended)) {
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* TODO: Merge {@link com.jetbrains.python.psi.impl.PyExpressionEvaluator}, PythonDataflowUtil, {@link com.jetbrains.python.psi.impl.PyConstantExpressionEvaluator} and {@link com.jetbrains.python.psi.impl.PyEvaluator} and all its inheritors and improve Abstract Interpretation
|
||||
* TODO: Merge PythonDataflowUtil, {@link com.jetbrains.python.psi.impl.PyConstantExpressionEvaluator} and {@link com.jetbrains.python.psi.impl.PyEvaluator} and all its inheritors and improve Abstract Interpretation
|
||||
* @author yole
|
||||
*/
|
||||
public class PyEvaluator {
|
||||
@@ -49,25 +49,7 @@ public class PyEvaluator {
|
||||
return evaluate(((PyParenthesizedExpression)expr).getContainedExpression());
|
||||
}
|
||||
if (expr instanceof PySequenceExpression) {
|
||||
PyExpression[] elements = ((PySequenceExpression)expr).getElements();
|
||||
if (expr instanceof PyDictLiteralExpression) {
|
||||
Map<Object, Object> result = new HashMap<Object, Object>();
|
||||
for (PyKeyValueExpression keyValueExpression : ((PyDictLiteralExpression)expr).getElements()) {
|
||||
Object dictKey = evaluate(keyValueExpression.getKey());
|
||||
if (dictKey != null) {
|
||||
PyExpression value = keyValueExpression.getValue();
|
||||
result.put(dictKey, myEvaluateCollectionItems ? evaluate(value) : value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
for (PyExpression element : elements) {
|
||||
result.add(myEvaluateCollectionItems ? evaluate(element) : element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return evaluateSequenceExpression((PySequenceExpression)expr);
|
||||
}
|
||||
if (expr instanceof PyCallExpression) {
|
||||
return evaluateCall((PyCallExpression)expr);
|
||||
@@ -92,7 +74,34 @@ public class PyEvaluator {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object concatenate(Object lhs, Object rhs) {
|
||||
/**
|
||||
* Evaluates some sequence (tuple, list)
|
||||
* @param expr seq expression
|
||||
* @return evaluated seq
|
||||
*/
|
||||
protected Object evaluateSequenceExpression(PySequenceExpression expr) {
|
||||
PyExpression[] elements = expr.getElements();
|
||||
if (expr instanceof PyDictLiteralExpression) {
|
||||
Map<Object, Object> result = new HashMap<Object, Object>();
|
||||
for (PyKeyValueExpression keyValueExpression : ((PyDictLiteralExpression)expr).getElements()) {
|
||||
Object dictKey = evaluate(keyValueExpression.getKey());
|
||||
if (dictKey != null) {
|
||||
PyExpression value = keyValueExpression.getValue();
|
||||
result.put(dictKey, myEvaluateCollectionItems ? evaluate(value) : value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
for (PyExpression element : elements) {
|
||||
result.add(myEvaluateCollectionItems ? evaluate(element) : element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public Object concatenate(Object lhs, Object rhs) {
|
||||
if (lhs instanceof String && rhs instanceof String) {
|
||||
return (String)lhs + (String)rhs;
|
||||
}
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Engine to evaluate expressions.
|
||||
* <p/>
|
||||
* Supports references and concatinations (sometimes!)
|
||||
*
|
||||
* @author Ilya.Kazakevich
|
||||
* @see {@link com.jetbrains.python.psi.impl.PyBlockEvaluator} (TODO: merge both classes?)
|
||||
*/
|
||||
public final class PyExpressionEvaluator {
|
||||
private static final int MAX_STEP = 100;
|
||||
|
||||
private PyExpressionEvaluator() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate expression to string
|
||||
*
|
||||
* @param expression expression to evaluate
|
||||
* @return string (or empty if cant evaluate)
|
||||
*/
|
||||
@NotNull
|
||||
public static String evaluateString(@NotNull final PyExpression expression) {
|
||||
final List<PyStringLiteralExpression> expressions = evaluateRaw(expression, PyStringLiteralExpression.class);
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (final PyStringLiteralExpression literalExpression : expressions) {
|
||||
builder.append(literalExpression.getStringValue());
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate expression to long
|
||||
*
|
||||
* @param expression expression to evaluate
|
||||
* @return long (or 0 if cant evaluate)
|
||||
*/
|
||||
public static long evaluateLong(@NotNull final PyExpression expression) {
|
||||
final List<PyNumericLiteralExpression> expressions = evaluateRaw(expression, PyNumericLiteralExpression.class);
|
||||
long result = 0L;
|
||||
for (final PyNumericLiteralExpression numericLiteralExpression : expressions) {
|
||||
final Long value = numericLiteralExpression.getLongValue();
|
||||
result += value != null ? value : 0L;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate expression to pack of elements (some iterables could be evaluated to it)
|
||||
*
|
||||
* @param expression expression to evaluate
|
||||
* @param aClass expected class of elements
|
||||
* @return pack of elements (or empty if cant evaluate)
|
||||
*/
|
||||
@NotNull
|
||||
public static <T extends PyElement> List<T> evaluateIterable(@NotNull final PyExpression expression, @NotNull final Class<T> aClass) {
|
||||
final List<T> list = new ArrayList<T>();
|
||||
for (final PyElement possibleIterable : evaluateRaw(expression, PyElement.class)) {
|
||||
if ((possibleIterable instanceof PyParenthesizedExpression) || (possibleIterable instanceof PyListLiteralExpression)) {
|
||||
list.addAll(PsiTreeUtil.findChildrenOfType(possibleIterable, aClass));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates expression to some element
|
||||
* @param expression expression to evaluate
|
||||
* @param aClass expected element type
|
||||
* @param <T> expected element type
|
||||
* @return element or null if can't evaluate
|
||||
*/
|
||||
@Nullable
|
||||
public static <T extends PyElement> T evaluateOne(@NotNull final PyExpression expression, @NotNull final Class<T> aClass) {
|
||||
final List<T> list = evaluateRaw(expression, aClass);
|
||||
if (list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluates expression to one or more elements (all elements should be concatinated).
|
||||
* I.e: i = 1 + 2. Evaluating "i" would lead to "1" and "2" separately (and not summed like in {@link #evaluateLong(com.jetbrains.python.psi.PyExpression)}
|
||||
* @param expression expression to evaluate
|
||||
* @param aClass expected elements type
|
||||
* @param <T> expected elements type
|
||||
* @return a pack of elements to concatinate or empty if can't evaluate
|
||||
*/
|
||||
@NotNull
|
||||
public static <T extends PyElement> List<T> evaluateRaw(@NotNull final PyExpression expression, @NotNull final Class<T> aClass) {
|
||||
int step = 0;
|
||||
PyElement currentElement = expression;
|
||||
final List<T> result = new ArrayList<T>();
|
||||
while (step < MAX_STEP) {
|
||||
PyElement newElement = null;
|
||||
|
||||
// TODO: Use visitor?
|
||||
if (currentElement instanceof PyReferenceExpression) {
|
||||
newElement = PyUtil.as(((PyReferenceExpression)currentElement).getReference().resolve(), PyElement.class);
|
||||
}
|
||||
else if (currentElement instanceof PyTargetExpression) {
|
||||
newElement = ((PyTargetExpression)currentElement).findAssignedValue();
|
||||
}
|
||||
else if (currentElement instanceof PyBinaryExpression) {
|
||||
final PyBinaryExpression newExpression = (PyBinaryExpression)currentElement;
|
||||
final PyElementType operator = newExpression.getOperator();
|
||||
if (PyTokenTypes.PLUS.equals(operator)) {
|
||||
final PyExpression leftExpression = newExpression.getLeftExpression();
|
||||
final PyExpression rightExpression = newExpression.getRightExpression();
|
||||
if (leftExpression != null) {
|
||||
result.addAll(evaluateRaw(leftExpression, aClass));
|
||||
}
|
||||
if (rightExpression != null) {
|
||||
result.addAll(evaluateRaw(rightExpression, aClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newElement == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentElement = newElement;
|
||||
step++;
|
||||
}
|
||||
final T elementToAdd = PyUtil.as(currentElement, aClass);
|
||||
if (elementToAdd != null) {
|
||||
result.add(elementToAdd);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyExpressionEvaluator;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests {@link com.jetbrains.python.psi.impl.PyExpressionEvaluator}
|
||||
*
|
||||
* @author Ilya.Kazakevich
|
||||
*/
|
||||
public class PyExpressionEvaluatorTest extends PyTestCase {
|
||||
|
||||
public void testLiteralReferences() {
|
||||
final PyTargetExpression myValue = createFileAndExpression("my_value",
|
||||
"x = 2",
|
||||
"y = x",
|
||||
"my_value = y"
|
||||
);
|
||||
final List<PyNumericLiteralExpression> result = PyExpressionEvaluator.evaluateRaw(myValue, PyNumericLiteralExpression.class);
|
||||
Assert.assertThat("Expected list of 1 long element", result.size(), Matchers.is(1));
|
||||
Assert.assertNotNull("Failed to evaluate chain of literals (got null)", result);
|
||||
final PyNumericLiteralExpression resultElement = result.get(0);
|
||||
Assert.assertThat("Evaluated incorrectly", resultElement.getLongValue(), Matchers.equalTo(2L));
|
||||
}
|
||||
|
||||
|
||||
public void testCall() {
|
||||
final PyTargetExpression myValue = createFileAndExpression("my_value",
|
||||
"x = abs(42)",
|
||||
"y = x",
|
||||
"my_value = y"
|
||||
);
|
||||
final List<PyCallExpression> result = PyExpressionEvaluator.evaluateRaw(myValue, PyCallExpression.class);
|
||||
Assert.assertNotNull("Failed to evaluate chain of functions (got null)", result);
|
||||
Assert.assertThat("Expected list of 1 call element", result.size(), Matchers.is(1));
|
||||
final PyExpression callee = result.get(0).getCallee();
|
||||
Assert.assertNotNull("Found empty callee", callee);
|
||||
Assert.assertThat("Evaluated incorrectly", callee.getName(), Matchers.equalTo("abs"));
|
||||
}
|
||||
|
||||
public void testStringConcat() {
|
||||
final PyTargetExpression myValue = createFileAndExpression("my_value",
|
||||
"x = 'go'",
|
||||
"y = x + ' away'",
|
||||
"my_value = y"
|
||||
);
|
||||
|
||||
final List<PyStringLiteralExpression> expressions = PyExpressionEvaluator.evaluateRaw(myValue, PyStringLiteralExpression.class);
|
||||
Assert.assertThat("Expected list of 2 string elements", expressions.size(), Matchers.is(2));
|
||||
Assert.assertThat("Evaluated incorrectly", expressions.get(0).getStringValue(), Matchers.equalTo("go"));
|
||||
Assert.assertThat("Evaluated incorrectly", expressions.get(1).getStringValue(), Matchers.equalTo(" away"));
|
||||
}
|
||||
|
||||
public void testNumberConcat() {
|
||||
final PyTargetExpression myValue = createFileAndExpression("my_value",
|
||||
"x = 2",
|
||||
"y = x + 1",
|
||||
"my_value = y"
|
||||
);
|
||||
|
||||
final List<PyNumericLiteralExpression> expressions = PyExpressionEvaluator.evaluateRaw(myValue, PyNumericLiteralExpression.class);
|
||||
Assert.assertThat("Expected list of 2 num elements", expressions.size(), Matchers.is(2));
|
||||
Assert.assertThat("Evaluated incorrectly", expressions.get(0).getLongValue(), Matchers.equalTo(2L));
|
||||
Assert.assertThat("Evaluated incorrectly", expressions.get(1).getLongValue(), Matchers.equalTo(1L));
|
||||
}
|
||||
|
||||
public void testNumber() {
|
||||
final long result = PyExpressionEvaluator.evaluateLong(createFileAndExpression("my_value", "x = 2", " y = 3", "my_value = x + y + 1"));
|
||||
Assert.assertThat("Error summarizing numbers", result, Matchers.is(6L));
|
||||
}
|
||||
|
||||
public void testString() {
|
||||
final String result = PyExpressionEvaluator.evaluateString(createFileAndExpression("my_value",
|
||||
"x = 'hello'",
|
||||
" y = \" there\"",
|
||||
"my_value = x + y + '!'"));
|
||||
Assert.assertThat("Error in string concat", result, Matchers.is("hello there!"));
|
||||
}
|
||||
|
||||
public void testIterableTuples() {
|
||||
final List<PyStringLiteralExpression> value = PyExpressionEvaluator.evaluateIterable(createFileAndExpression("my_value",
|
||||
"x = ('hello', 'from')",
|
||||
" y = ('here', '!')",
|
||||
"my_value = x + y"),
|
||||
PyStringLiteralExpression.class
|
||||
);
|
||||
Assert.assertThat("Expected list of elements", value.size(), Matchers.is(4));
|
||||
Assert.assertThat("Evaluated incorrectly", value.get(0).getStringValue(), Matchers.equalTo("hello"));
|
||||
Assert.assertThat("Evaluated incorrectly", value.get(1).getStringValue(), Matchers.equalTo("from"));
|
||||
Assert.assertThat("Evaluated incorrectly", value.get(2).getStringValue(), Matchers.equalTo("here"));
|
||||
Assert.assertThat("Evaluated incorrectly", value.get(3).getStringValue(), Matchers.equalTo("!"));
|
||||
}
|
||||
|
||||
public void testIterableLists() {
|
||||
final List<PyStringLiteralExpression> value = PyExpressionEvaluator.evaluateIterable(createFileAndExpression("my_value",
|
||||
"x = ['hello', 'from']",
|
||||
" y = ['here'] + ['!']",
|
||||
"my_value = x + y"),
|
||||
PyStringLiteralExpression.class
|
||||
);
|
||||
Assert.assertThat("Expected list of elements", value.size(), Matchers.is(4));
|
||||
Assert.assertThat("Evaluated incorrectly", value.get(0).getStringValue(), Matchers.equalTo("hello"));
|
||||
Assert.assertThat("Evaluated incorrectly", value.get(1).getStringValue(), Matchers.equalTo("from"));
|
||||
Assert.assertThat("Evaluated incorrectly", value.get(2).getStringValue(), Matchers.equalTo("here"));
|
||||
Assert.assertThat("Evaluated incorrectly", value.get(3).getStringValue(), Matchers.equalTo("!"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create file, fill it with data and return some expression from it
|
||||
*
|
||||
* @param varName name of expression to return
|
||||
* @param lines lines of code
|
||||
* @return expression
|
||||
*/
|
||||
@NotNull
|
||||
private PyTargetExpression createFileAndExpression(@NotNull final String varName, @NotNull final String... lines) {
|
||||
final PsiFile file =
|
||||
PyElementGenerator.getInstance(myFixture.getProject()).createDummyFile(LanguageLevel.PYTHON27, StringUtil.join(lines, "\n"));
|
||||
assert file instanceof PyFile : "PyElementGenerator created not py file?";
|
||||
final PyFile pyFile = (PyFile)file;
|
||||
final PyTargetExpression result = pyFile.findTopLevelAttribute(varName);
|
||||
assert result != null : "No var with name " + varName + " found";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user