Merge branch 'python-fixes'

This commit is contained in:
Andrey Vlasovskikh
2012-07-26 21:00:01 +04:00
6 changed files with 36 additions and 45 deletions
@@ -44,7 +44,7 @@ public class PyFileElementType extends IStubFileElementType<PyFileStub> {
@Override
public int getStubVersion() {
return 43;
return 44;
}
@Nullable
@@ -49,8 +49,8 @@ public abstract class PropertyBunch<MType> {
* @param ref a reference as an argument in property() call
* @return value we want to store (resolved callable, name, etc)
*/
@Nullable
protected abstract MType translate(@NotNull PyExpression ref);
@NotNull
protected abstract Maybe<MType> translate(@Nullable PyExpression ref);
@Nullable
public static PyCallExpression findPropertyCallSite(@Nullable PyExpression source) {
@@ -60,20 +60,25 @@ public abstract class PropertyBunch<MType> {
if (callee instanceof PyReferenceExpression) {
PyReferenceExpression ref = (PyReferenceExpression)callee;
if (ref.getQualifier() != null) return null;
boolean is_inside_builtins = false;
PsiFile psifile = source.getContainingFile();
is_inside_builtins = psifile != null && psifile.getUserData(PyBuiltinCache.MARKER_KEY) != null;
if (PyNames.PROPERTY.equals(callee.getName()) && (is_inside_builtins || !resolvesLocally(ref))) {
// we assume that a non-local name 'property' is a built-in name.
// ref.resolve() is not used because we run in stub building phase where resolve() is frowned upon.
// NOTE: this logic fails if (quite unusually) name 'property' is directly imported from builtins.
return call;
if (PyNames.PROPERTY.equals(callee.getName())) {
PsiFile file = source.getContainingFile();
if (isBuiltinFile(file) || !resolvesLocally(ref)) {
// we assume that a non-local name 'property' is a built-in name.
// ref.resolve() is not used because we run in stub building phase where resolve() is frowned upon.
// NOTE: this logic fails if (quite unusually) name 'property' is directly imported from builtins.
return call;
}
}
}
}
return null;
}
private static boolean isBuiltinFile(PsiFile file) {
final String name = file.getName();
return PyBuiltinCache.BUILTIN_FILE.equals(name) || PyBuiltinCache.BUILTIN_FILE_3K.equals(name);
}
/**
* Resolve in containing file only.
* @param ref what to resolve
@@ -129,17 +134,13 @@ public abstract class PropertyBunch<MType> {
}
}
}
target.myGetter = translateIfSet(target, accessors [0]);
target.mySetter = translateIfSet(target, accessors [1]);
target.myDeleter = translateIfSet(target, accessors [2]);
target.myGetter = target.translate(accessors[0]);
target.mySetter = target.translate(accessors[1]);
target.myDeleter = target.translate(accessors[2]);
target.myDoc = doc;
return true;
}
}
return false;
}
private static <MType> Maybe<MType> translateIfSet(PropertyBunch<MType> target, PyExpression accessor) {
return new Maybe<MType>(accessor == null ? null : target.translate(accessor));
}
}
@@ -9,7 +9,6 @@ import com.intellij.openapi.roots.JdkOrderEntry;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.impl.ModuleLibraryOrderEntryImpl;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
@@ -149,15 +148,9 @@ public class PyBuiltinCache {
public PyBuiltinCache() {
}
public static final Key<String> MARKER_KEY = new Key<String>("python.builtins.skeleton.file");
public PyBuiltinCache(@Nullable final PyFile builtins, @Nullable PyFile exceptions) {
myBuiltinsFile = builtins;
myExceptionsFile = exceptions;
if (myBuiltinsFile != null) {
myBuiltinsFile.putUserData(MARKER_KEY, ""); // mark this file as builtins
}
}
@Nullable
@@ -39,8 +39,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.*;
import static com.jetbrains.python.psi.stubs.PyTargetExpressionStub.InitializerType.CallExpression;
/**
* @author yole
*/
@@ -603,14 +601,6 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
if (propertyProcessor == null || propertyProcessor.process(property)) return property;
}
}
final PyQualifiedName initializer = targetStub.getInitializer();
if (targetStub.getInitializerType() == CallExpression && initializer != null && PyNames.PROPERTY.equals(initializer.toString())) {
final PropertyImpl property = new PropertyImpl(targetStub.getName(), UNKNOWN_CALL, UNKNOWN_CALL, UNKNOWN_CALL,
null, targetStub.getPsi());
if (propertyProcessor == null || propertyProcessor.process(property)) {
return property;
}
}
}
}
}
@@ -740,21 +730,24 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
throw new IllegalArgumentException("Unknown direction " + PyUtil.nvl(direction));
}
@Nullable
@NotNull
@Override
protected Callable translate(@NotNull PyExpression expr) {
if (PyNames.NONE.equals(expr.getName())) return null; // short-circuit a common case
protected Maybe<Callable> translate(@Nullable PyExpression expr) {
if (expr == null) {
return NONE;
}
if (PyNames.NONE.equals(expr.getName())) return NONE; // short-circuit a common case
if (expr instanceof Callable) {
return (Callable)expr;
return new Maybe<Callable>((Callable)expr);
}
final PsiReference ref = expr.getReference();
if (ref != null) {
PsiElement something = ref.resolve();
if (something instanceof Callable) {
return (Callable)something;
return new Maybe<Callable>((Callable)something);
}
}
return null;
return NONE;
}
public String toString() {
@@ -22,10 +22,14 @@ import java.io.IOException;
*/
public class PropertyStubStorage extends PropertyBunch<String> implements CustomTargetExpressionStub {
@Nullable
@NotNull
@Override
protected String translate(@NotNull PyExpression ref) {
return ref.getName();
protected Maybe<String> translate(@Nullable PyExpression ref) {
if (ref != null) {
final String name = ref.getName();
return name != null ? new Maybe<String>(name) : unknown;
}
return none;
}
private static final String IMPOSSIBLE_NAME = "#";
@@ -73,7 +73,7 @@ public class PyClassicPropertyTest extends PyTestCase {
assertEquals("v3", site.getText());
accessor = p.getGetter();
assertTrue(accessor.isDefined());
assertFalse(accessor.isDefined());
accessor = p.getSetter();
assertTrue(accessor.isDefined());