com.jetbrains.python.psi.impl.PyEvaluator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of python-community Show documentation
Show all versions of python-community Show documentation
A packaging of the IntelliJ Community Edition python-community library.
This is release number 1 of trunk branch 142.
The newest version!
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.psi.impl;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.PythonFQDNNames;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* 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 {
private Set myVisited = new HashSet();
private Map myNamespace;
private boolean myEvaluateCollectionItems = true;
private boolean myEvaluateKeys = true;
public void setNamespace(Map namespace) {
myNamespace = namespace;
}
public void setEvaluateCollectionItems(boolean evaluateCollectionItems) {
myEvaluateCollectionItems = evaluateCollectionItems;
}
/**
* @param evaluateKeys evaluate keys for dicts or not (i.e. you wanna see string or StringLiteralExpressions as keys)
*/
public void setEvaluateKeys(final boolean evaluateKeys) {
myEvaluateKeys = evaluateKeys;
}
@Nullable
public Object evaluate(@Nullable PyExpression expr) {
if (expr == null || myVisited.contains(expr)) {
return null;
}
myVisited.add(expr);
if (expr instanceof PyParenthesizedExpression) {
return evaluate(((PyParenthesizedExpression)expr).getContainedExpression());
}
if (expr instanceof PySequenceExpression) {
return evaluateSequenceExpression((PySequenceExpression)expr);
}
final Boolean booleanExpression = getBooleanExpression(expr);
if (booleanExpression != null) { // support bool
return booleanExpression;
}
if (expr instanceof PyCallExpression) {
return evaluateCall((PyCallExpression)expr);
}
else if (expr instanceof PyReferenceExpression) {
return evaluateReferenceExpression((PyReferenceExpression)expr);
}
else if (expr instanceof PyStringLiteralExpression) {
return ((PyStringLiteralExpression)expr).getStringValue();
}
else if (expr instanceof PyBinaryExpression) {
PyBinaryExpression binaryExpr = (PyBinaryExpression)expr;
PyElementType op = binaryExpr.getOperator();
if (op == PyTokenTypes.PLUS) {
Object lhs = evaluate(binaryExpr.getLeftExpression());
Object rhs = evaluate(binaryExpr.getRightExpression());
if (lhs != null && rhs != null) {
return concatenate(lhs, rhs);
}
}
}
return null;
}
/**
* TODO: Move to PyExpression? PyUtil?
* True/False is bool literal in Py3K, but reference in Python2.
*
* @param expression expression to check
* @return true if expression is boolean
*/
@Nullable
private static Boolean getBooleanExpression(@NotNull final PyExpression expression) {
final boolean py3K = LanguageLevel.forElement(expression).isPy3K();
if ((py3K && (expression instanceof PyBoolLiteralExpression))) {
return ((PyBoolLiteralExpression)expression).getValue(); // Cool in Py2K
}
if ((!py3K && (expression instanceof PyReferenceExpression))) {
final String text = ((PyReferenceExpression)expression).getReferencedName(); // Ref in Python2
if (PyNames.TRUE.equals(text)) {
return true;
}
if (PyNames.FALSE.equals(text)) {
return false;
}
}
return null;
}
/**
* 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
© 2015 - 2025 Weber Informatics LLC | Privacy Policy