Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2013-01-25 12:11:45 +01:00
26 changed files with 366 additions and 255 deletions
+1
View File
@@ -49,3 +49,4 @@ pycharm-flask
pycharm-numpy
textmate
restClient
puppet
+1
View File
@@ -179,6 +179,7 @@ private layoutPlugins(layouts) {
include(name: "joni.jar")
}
}
layouts.layoutPlugin("puppet")
}
layouts.layoutPlugins()
+2 -2
View File
@@ -3,8 +3,8 @@
<id>org.jetbrains.plugins.rest</id>
<description>This plugin enables support for reStructuredText files (*.rst)</description>
<vendor>JetBrains</vendor>
<version>122.SNAPSHOT</version>
<idea-version since-build="124.0" until-build="126.9999"/>
<version>126.SNAPSHOT</version>
<idea-version since-build="126.0" until-build="126.9999"/>
<depends>com.intellij.modules.lang</depends>
<xi:include href="/META-INF/rest.xml" xpointer="xpointer(/idea-plugin/*)"/>
@@ -319,6 +319,7 @@
<localInspection language="Python" shortName="PyPackageRequirementsInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.requirements" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyPackageRequirementsInspection"/>
<localInspection language="Python" shortName="PyPep8Inspection" displayName="PEP 8 coding style violation" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyPep8Inspection"/>
<localInspection language="Python" shortName="PyDocstringTypesInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.docstring.types" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyDocstringTypesInspection"/>
<localInspection language="Python" shortName="PyShadowingBuiltinsInspection" displayName="Shadowing built-ins" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyShadowingBuiltinsInspection"/>
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType"/>
<liveTemplateMacro implementation="com.jetbrains.python.codeInsight.liveTemplates.CollectionElementNameMacro"/>
@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
/**
* User : catherine
@@ -37,19 +36,18 @@ public class PyTestFinder implements TestFinder {
PyDocStringOwner source = findSourceElement(element);
if (source == null) return Collections.emptySet();
String klassName = source.getName();
Pattern pattern = Pattern.compile(".*" + klassName + ".*");
String sourceName = source.getName();
List<Pair<? extends PsiNamedElement, Integer>> classesWithProximities = new ArrayList<Pair<? extends PsiNamedElement, Integer>>();
if (source instanceof PyClass) {
Collection<String> names = PyClassNameIndex.allKeys(element.getProject());
for (String eachName : names) {
if (pattern.matcher(eachName).matches()) {
if (eachName.contains(sourceName)) {
for (PyClass eachClass : PyClassNameIndex.find(eachName, element.getProject(), GlobalSearchScope.projectScope(element.getProject()))) {
if (PythonUnitTestUtil.isTestCaseClass(eachClass) || PythonDocTestUtil.isDocTestClass(eachClass)) {
classesWithProximities.add(
new Pair<PsiNamedElement, Integer>(eachClass, TestFinderHelper.calcTestNameProximity(klassName, eachName)));
new Pair<PsiNamedElement, Integer>(eachClass, TestFinderHelper.calcTestNameProximity(sourceName, eachName)));
}
}
}
@@ -58,12 +56,12 @@ public class PyTestFinder implements TestFinder {
else {
Collection<String> names = PyFunctionNameIndex.allKeys(element.getProject());
for (String eachName : names) {
if (pattern.matcher(eachName).matches()) {
if (eachName.contains(sourceName)) {
for (PyFunction eachFunction : PyFunctionNameIndex.find(eachName, element.getProject(), GlobalSearchScope.projectScope(element.getProject()))) {
if (PythonUnitTestUtil.isTestCaseFunction(
eachFunction) || PythonDocTestUtil.isDocTestFunction(eachFunction)) {
classesWithProximities.add(
new Pair<PsiNamedElement, Integer>(eachFunction, TestFinderHelper.calcTestNameProximity(klassName, eachName)));
new Pair<PsiNamedElement, Integer>(eachFunction, TestFinderHelper.calcTestNameProximity(sourceName, eachName)));
}
}
}
@@ -41,10 +41,9 @@ import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.io.IOUtil;
import com.intellij.util.net.NetUtils;
import com.intellij.util.ui.UIUtil;
import com.jetbrains.django.run.Runner;
import com.jetbrains.django.run.ProcessRunner;
import com.intellij.remotesdk.RemoteSdkData;
import com.intellij.remotesdk.RemoteSshProcess;
import com.jetbrains.python.PythonHelpersLocator;
@@ -247,7 +246,7 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
}
else {
myCommandLine = myCommandLineArgumentsProvider.getCommandLineString();
final Process server = Runner
final Process server = ProcessRunner
.createProcess(getWorkingDir(), myCommandLineArgumentsProvider.getAdditionalEnvs(), myCommandLineArgumentsProvider.getArguments());
try {
myPydevConsoleCommunication = new PydevConsoleCommunication(getProject(), myPorts[0], server, myPorts[1]);
@@ -278,7 +277,7 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
RemoteSshProcess remoteProcess =
manager.createRemoteProcess(getProject(), data, commandLine, false);
manager.createRemoteProcess(getProject(), data, commandLine, true);
Pair<Integer, Integer> remotePorts = getRemotePortsFromProcess(remoteProcess);
@@ -36,7 +36,7 @@
</constraints>
<properties>
<labelFor value="63296"/>
<text value="&amp;URL Pattern:"/>
<text value="&amp;URL/Path Pattern:"/>
</properties>
</component>
<component id="63296" class="javax.swing.JTextField" binding="myURLPatternTextField" default-binding="true">
@@ -49,11 +49,7 @@ public class PyCallingNonCallableInspection extends PyInspection {
final PyExpression callee = decorator.getCallee();
checkCallable(decorator, callee, null);
if (decorator.hasArgumentList()) {
final Callable callable = decorator.resolveCalleeFunction(resolveWithoutImplicits());
if (callable != null) {
final PyReferenceExpression callSite = callee instanceof PyReferenceExpression ? (PyReferenceExpression)callee : null;
checkCallable(decorator, null, callable.getReturnType(myTypeEvalContext, callSite));
}
checkCallable(decorator, decorator, null);
}
}
}
@@ -0,0 +1,68 @@
package com.jetbrains.python.inspections;
import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiNameIdentifierOwner;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Warns about shadowing built-in names.
*
* TODO: Merge into PyRedeclarationInspection and detect all shadowed names
*
* @author vlan
*/
public class PyShadowingBuiltinsInspection extends PyInspection {
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder,
boolean isOnTheFly,
@NotNull LocalInspectionToolSession session) {
return new Visitor(holder, session);
}
private static class Visitor extends PyInspectionVisitor {
public Visitor(@Nullable ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
super(holder, session);
}
@Override
public void visitPyClass(@NotNull PyClass node) {
processElement(node);
}
@Override
public void visitPyFunction(@NotNull PyFunction node) {
if (node.getContainingClass() == null) {
processElement(node);
}
}
@Override
public void visitPyNamedParameter(@NotNull PyNamedParameter node) {
processElement(node);
}
@Override
public void visitPyTargetExpression(@NotNull PyTargetExpression node) {
processElement(node);
}
private void processElement(@NotNull PsiNameIdentifierOwner element) {
final String name = element.getName();
if (name != null) {
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(element);
final PsiElement builtin = builtinCache.getByName(name);
if (builtin != null && !PyUtil.inSameFile(builtin, element)) {
final PsiElement identifier = element.getNameIdentifier();
registerProblem(identifier != null ? identifier : element, "Shadows a built-in with the same name");
}
}
}
}
}
@@ -64,7 +64,7 @@ public class PyTypeCheckerInspection extends PyInspection {
final Map<PyGenericType, PyType> substitutions = new LinkedHashMap<PyGenericType, PyType>();
final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, myTypeEvalContext);
if (results != null) {
substitutions.putAll(PyTypeChecker.collectCallGenerics(results.getFunction(), results.getReceiver(), myTypeEvalContext));
substitutions.putAll(PyTypeChecker.collectCallGenerics(results.getCallable(), results.getReceiver(), myTypeEvalContext));
for (Map.Entry<PyExpression, PyNamedParameter> entry : results.getArguments().entrySet()) {
final PyNamedParameter p = entry.getValue();
if (p.isPositionalContainer() || p.isKeywordContainer()) {
@@ -672,8 +672,8 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
return true;
}
if (qtype instanceof PyFunctionType) {
final PyFunction function = ((PyFunctionType)qtype).getFunction();
if (function.getDecoratorList() != null) {
final Callable callable = ((PyFunctionType)qtype).getCallable();
if (callable instanceof PyFunction && ((PyFunction)callable).getDecoratorList() != null) {
return true;
}
}
@@ -30,6 +30,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.remotesdk.RemoteCredentials;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.SystemProperties;
@@ -627,7 +628,7 @@ public class PyPackageManagerImpl extends PyPackageManager {
private String getHelperPath(String helper) {
String helperPath;
final SdkAdditionalData sdkData = mySdk.getSdkAdditionalData();
if (sdkData instanceof RemoteSdkData) {
if (sdkData instanceof RemoteCredentials) {
final RemoteSdkData remoteSdkData = (RemoteSdkData)sdkData;
helperPath = new RemoteFile(remoteSdkData.getHelpersPath(),
helper).getPath();
@@ -644,7 +645,7 @@ public class PyPackageManagerImpl extends PyPackageManager {
@Nullable String workingDir)
throws PyExternalProcessException {
final SdkAdditionalData sdkData = mySdk.getSdkAdditionalData();
if (sdkData instanceof RemoteSdkData) { //remote interpreter
if (sdkData instanceof RemoteCredentials) { //remote interpreter
final RemoteSdkData remoteSdkData = (RemoteSdkData)sdkData;
final PythonRemoteInterpreterManager manager = PythonRemoteInterpreterManager.getInstance();
if (manager != null) {
@@ -111,7 +111,7 @@ public class PyBinaryExpressionImpl extends PyElementImpl implements PyBinaryExp
public PyType getType(@NotNull TypeEvalContext context) {
final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCall(this, context);
if (results != null) {
final PyType type = results.getFunction().getReturnType(context, this);
final PyType type = results.getCallable().getReturnType(context, this);
if (!PyTypeChecker.isUnknown(type) && !(type instanceof PyNoneType)) {
return type;
}
@@ -347,7 +347,7 @@ public class PyBuiltinCache {
return true;
}
else if (type instanceof PyFunctionType) {
return ((PyFunctionType)type).getFunction().isValid();
return ((PyFunctionType)type).getCallable().isValid();
}
return true;
}
@@ -1,13 +1,17 @@
package com.jetbrains.python.psi.impl;
import com.intellij.codeInsight.completion.CompletionUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.QualifiedResolveResult;
import com.jetbrains.python.psi.types.*;
import com.jetbrains.python.toolbox.Maybe;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -337,4 +341,199 @@ public class PyCallExpressionHelper {
}
return null;
}
public static PyType getCallType(@NotNull PyCallExpression call, @NotNull TypeEvalContext context) {
if (!TypeEvalStack.mayEvaluate(call)) {
return null;
}
try {
PyExpression callee = call.getCallee();
if (callee instanceof PyReferenceExpression) {
// hardwired special cases
if (PyNames.SUPER.equals(callee.getText())) {
final Maybe<PyType> superCallType = getSuperCallType(call, context);
if (superCallType.isDefined()) {
return superCallType.value();
}
}
if ("type".equals(callee.getText())) {
final PyExpression[] args = call.getArguments();
if (args.length == 1) {
final PyExpression arg = args[0];
final PyType argType = arg.getType(context);
if (argType instanceof PyClassType) {
final PyClassType classType = (PyClassType)argType;
if (!classType.isDefinition()) {
final PyClass cls = classType.getPyClass();
return cls.getType(context);
}
}
else {
return null;
}
}
}
// normal cases
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
ResolveResult[] targets = ((PyReferenceExpression)callee).getReference(resolveContext).multiResolve(false);
if (targets.length > 0) {
PsiElement target = targets[0].getElement();
if (target == null) {
return null;
}
PyClass cls = null;
PyFunction init = null;
if (target instanceof PyClass) {
cls = (PyClass)target;
init = cls.findInitOrNew(true);
}
else if (target instanceof PyFunction) {
final PyFunction f = (PyFunction)target;
if (PyNames.INIT.equals(f.getName())) {
init = f;
cls = f.getContainingClass();
}
}
if (init != null) {
final PyType t = init.getReturnType(context, (PyReferenceExpression)callee);
if (cls != null) {
if (init.getContainingClass() != cls) {
if (t instanceof PyCollectionType) {
final PyType elementType = ((PyCollectionType)t).getElementType(context);
return new PyCollectionTypeImpl(cls, false, elementType);
}
return new PyClassTypeImpl(cls, false);
}
}
if (t != null && !(t instanceof PyNoneType)) {
if (t instanceof PyTypeReference) {
PyType resolved = ((PyTypeReference)t).resolve(callee, context);
if (resolved == null && cls != null) {
return PyUnionType.createWeakType(new PyClassTypeImpl(cls, false));
}
}
return t;
}
}
if (cls != null) {
return new PyClassTypeImpl(cls, false);
}
final PyType providedType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(target, context, call);
if (providedType != null) {
if (providedType instanceof PyClassType) {
return ((PyClassType)providedType).toInstance();
}
return providedType;
}
if (target instanceof Callable) {
final Callable callable = (Callable)target;
PyType returnType = callable.getReturnType(context, (PyReferenceExpression)callee);
if (returnType != null) {
return returnType;
}
return new PyReturnTypeReference(callable);
}
}
}
if (callee == null) {
return null;
}
else {
final PyType type = context.getType(callee);
if (type instanceof PyCallableType) {
final PyQualifiedExpression callSite = callee instanceof PyQualifiedExpression ? (PyQualifiedExpression)callee : null;
return ((PyCallableType) type).getCallType(context, callSite);
}
return null;
}
}
finally {
TypeEvalStack.evaluated(call);
}
}
@NotNull
private static Maybe<PyType> getSuperCallType(@NotNull PyCallExpression call, TypeEvalContext context) {
final PyExpression callee = call.getCallee();
if (callee instanceof PyReferenceExpression) {
PsiElement must_be_super_init = ((PyReferenceExpression)callee).getReference().resolve();
if (must_be_super_init instanceof PyFunction) {
PyClass must_be_super = ((PyFunction)must_be_super_init).getContainingClass();
if (must_be_super == PyBuiltinCache.getInstance(call).getClass(PyNames.SUPER)) {
PyArgumentList arglist = call.getArgumentList();
if (arglist != null) {
final PyClass containingClass = PsiTreeUtil.getParentOfType(call, PyClass.class);
PyExpression[] args = arglist.getArguments();
if (args.length > 1) {
PyExpression first_arg = args[0];
if (first_arg instanceof PyReferenceExpression) {
final PyReferenceExpression firstArgRef = (PyReferenceExpression)first_arg;
final PyExpression qualifier = firstArgRef.getQualifier();
if (qualifier != null && PyNames.CLASS.equals(firstArgRef.getReferencedName())) {
final PsiReference qRef = qualifier.getReference();
final PsiElement element = qRef == null ? null : qRef.resolve();
if (element instanceof PyParameter) {
final PyParameterList parameterList = PsiTreeUtil.getParentOfType(element, PyParameterList.class);
if (parameterList != null && element == parameterList.getParameters()[0]) {
return new Maybe<PyType>(getSuperCallTypeForArguments(context, containingClass, args[1]));
}
}
}
PsiElement possible_class = firstArgRef.getReference().resolve();
if (possible_class instanceof PyClass && ((PyClass)possible_class).isNewStyleClass()) {
final PyClass first_class = (PyClass)possible_class;
return new Maybe<PyType>(getSuperCallTypeForArguments(context, first_class, args[1]));
}
}
}
else if (((PyFile)call.getContainingFile()).getLanguageLevel().isPy3K() && containingClass != null) {
return new Maybe<PyType>(getSuperClassUnionType(containingClass));
}
}
}
}
}
return new Maybe<PyType>();
}
@Nullable
private static PyType getSuperCallTypeForArguments(TypeEvalContext context, PyClass firstClass, PyExpression second_arg) {
// check 2nd argument, too; it should be an instance
if (second_arg != null) {
PyType second_type = context.getType(second_arg);
if (second_type instanceof PyClassType) {
// imitate isinstance(second_arg, possible_class)
PyClass secondClass = ((PyClassType)second_type).getPyClass();
if (CompletionUtil.getOriginalOrSelf(firstClass) == secondClass) {
return getSuperClassUnionType(firstClass);
}
if (secondClass.isSubclass(firstClass)) {
final Iterator<PyClass> iterator = firstClass.iterateAncestorClasses().iterator();
if (iterator.hasNext()) {
return new PyClassTypeImpl(iterator.next(), false); // super(Foo, self) has type of Foo, modulo __get__()
}
}
}
}
return null;
}
@Nullable
private static PyType getSuperClassUnionType(@NotNull PyClass pyClass) {
// TODO: this is closer to being correct than simply taking first superclass type but still not entirely correct;
// super can also delegate to sibling types
// TODO handle __mro__ here
final PyClass[] supers = pyClass.getSuperClasses();
if (supers.length > 0) {
if (supers.length == 1) {
return new PyClassTypeImpl(supers[0], false);
}
List<PyType> superTypes = new ArrayList<PyType>();
for (PyClass aSuper : supers) {
superTypes.add(new PyClassTypeImpl(aSuper, false));
}
return PyUnionType.union(superTypes);
}
return null;
}
}
@@ -1,23 +1,14 @@
package com.jetbrains.python.psi.impl;
import com.intellij.codeInsight.completion.CompletionUtil;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.types.*;
import com.jetbrains.python.toolbox.Maybe;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author yole
*/
@@ -97,194 +88,6 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
}
public PyType getType(@NotNull TypeEvalContext context) {
if (!TypeEvalStack.mayEvaluate(this)) {
return null;
}
try {
PyExpression callee = getCallee();
if (callee instanceof PyReferenceExpression) {
// hardwired special cases
if (PyNames.SUPER.equals(callee.getText())) {
final Maybe<PyType> superCallType = getSuperCallType(callee, context);
if (superCallType.isDefined()) {
return superCallType.value();
}
}
if ("type".equals(callee.getText())) {
final PyExpression[] args = getArguments();
if (args.length == 1) {
final PyExpression arg = args[0];
final PyType argType = arg.getType(context);
if (argType instanceof PyClassType) {
final PyClassType classType = (PyClassType)argType;
if (!classType.isDefinition()) {
final PyClass cls = classType.getPyClass();
return cls.getType(context);
}
}
else {
return null;
}
}
}
// normal cases
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
ResolveResult[] targets = ((PyReferenceExpression)callee).getReference(resolveContext).multiResolve(false);
if (targets.length > 0) {
PsiElement target = targets[0].getElement();
if (target == null) {
return null;
}
PyClass cls = null;
PyFunction init = null;
if (target instanceof PyClass) {
cls = (PyClass)target;
init = cls.findInitOrNew(true);
}
else if (target instanceof PyFunction) {
final PyFunction f = (PyFunction)target;
if (PyNames.INIT.equals(f.getName())) {
init = f;
cls = f.getContainingClass();
}
}
if (init != null) {
final PyType t = init.getReturnType(context, (PyReferenceExpression)callee);
if (cls != null) {
if (init.getContainingClass() != cls) {
if (t instanceof PyCollectionType) {
final PyType elementType = ((PyCollectionType)t).getElementType(context);
return new PyCollectionTypeImpl(cls, false, elementType);
}
return new PyClassTypeImpl(cls, false);
}
}
if (t != null && !(t instanceof PyNoneType)) {
if (t instanceof PyTypeReference) {
PyType resolved = ((PyTypeReference)t).resolve(callee, context);
if (resolved == null && cls != null) {
return PyUnionType.createWeakType(new PyClassTypeImpl(cls, false));
}
}
return t;
}
}
if (cls != null) {
return new PyClassTypeImpl(cls, false);
}
final PyType providedType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(target, context, this);
if (providedType != null) {
if (providedType instanceof PyClassType) {
return ((PyClassType)providedType).toInstance();
}
return providedType;
}
if (target instanceof Callable) {
final Callable callable = (Callable)target;
PyType returnType = callable.getReturnType(context, (PyReferenceExpression)callee);
if (returnType != null) {
return returnType;
}
return new PyReturnTypeReference(callable);
}
}
}
if (callee == null) {
return null;
}
else {
final PyType type = context.getType(callee);
if (type instanceof PyCallableType) {
final PyQualifiedExpression callSite = callee instanceof PyQualifiedExpression ? (PyQualifiedExpression)callee : null;
return ((PyCallableType) type).getCallType(context, callSite);
}
return null;
}
}
finally {
TypeEvalStack.evaluated(this);
}
}
@NotNull
private Maybe<PyType> getSuperCallType(PyExpression callee, TypeEvalContext context) {
PsiElement must_be_super_init = ((PyReferenceExpression)callee).getReference().resolve();
if (must_be_super_init instanceof PyFunction) {
PyClass must_be_super = ((PyFunction)must_be_super_init).getContainingClass();
if (must_be_super == PyBuiltinCache.getInstance(this).getClass(PyNames.SUPER)) {
PyArgumentList arglist = getArgumentList();
if (arglist != null) {
final PyClass containingClass = PsiTreeUtil.getParentOfType(this, PyClass.class);
PyExpression[] args = arglist.getArguments();
if (args.length > 1) {
PyExpression first_arg = args[0];
if (first_arg instanceof PyReferenceExpression) {
final PyReferenceExpression firstArgRef = (PyReferenceExpression)first_arg;
final PyExpression qualifier = firstArgRef.getQualifier();
if (qualifier != null && PyNames.CLASS.equals(firstArgRef.getReferencedName())) {
final PsiReference qRef = qualifier.getReference();
final PsiElement element = qRef == null ? null : qRef.resolve();
if (element instanceof PyParameter) {
final PyParameterList parameterList = PsiTreeUtil.getParentOfType(element, PyParameterList.class);
if (parameterList != null && element == parameterList.getParameters()[0]) {
return new Maybe<PyType>(getSuperCallType(context, containingClass, args[1]));
}
}
}
PsiElement possible_class = firstArgRef.getReference().resolve();
if (possible_class instanceof PyClass && ((PyClass)possible_class).isNewStyleClass()) {
final PyClass first_class = (PyClass)possible_class;
return new Maybe<PyType>(getSuperCallType(context, first_class, args[1]));
}
}
}
else if (((PyFile)getContainingFile()).getLanguageLevel().isPy3K() && containingClass != null) {
return new Maybe<PyType>(getSuperClassUnionType(containingClass));
}
}
}
}
return new Maybe<PyType>();
}
@Nullable
private static PyType getSuperCallType(TypeEvalContext context, PyClass firstClass, PyExpression second_arg) {
// check 2nd argument, too; it should be an instance
if (second_arg != null) {
PyType second_type = context.getType(second_arg);
if (second_type instanceof PyClassType) {
// imitate isinstance(second_arg, possible_class)
PyClass secondClass = ((PyClassType)second_type).getPyClass();
if (CompletionUtil.getOriginalOrSelf(firstClass) == secondClass) {
return getSuperClassUnionType(firstClass);
}
if (secondClass.isSubclass(firstClass)) {
final Iterator<PyClass> iterator = firstClass.iterateAncestorClasses().iterator();
if (iterator.hasNext()) {
return new PyClassTypeImpl(iterator.next(), false); // super(Foo, self) has type of Foo, modulo __get__()
}
}
}
}
return null;
}
@Nullable
private static PyType getSuperClassUnionType(@NotNull PyClass pyClass) {
// TODO: this is closer to being correct than simply taking first superclass type but still not entirely correct;
// super can also delegate to sibling types
// TODO handle __mro__ here
final PyClass[] supers = pyClass.getSuperClasses();
if (supers.length > 0) {
if (supers.length == 1) {
return new PyClassTypeImpl(supers[0], false);
}
List<PyType> superTypes = new ArrayList<PyType>();
for (PyClass aSuper : supers) {
superTypes.add(new PyClassTypeImpl(aSuper, false));
}
return PyUnionType.union(superTypes);
}
return null;
return PyCallExpressionHelper.getCallType(this, context);
}
}
@@ -166,8 +166,7 @@ public class PyDecoratorImpl extends StubBasedPsiElementBase<PyDecoratorStub> im
}
}
// TODO: create a custom version of public PyType getType()
public PyType getType(@NotNull TypeEvalContext context) {
return null; //To change body of implemented methods use File | Settings | File Templates.
return PyCallExpressionHelper.getCallType(this, context);
}
}
@@ -5,6 +5,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyElementTypes;
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyFunctionType;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
@@ -23,7 +24,7 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp
}
public PyType getType(@NotNull TypeEvalContext context) {
return null;
return new PyFunctionType(this);
}
@NotNull
@@ -1,10 +1,7 @@
package com.jetbrains.python.psi.types;
import com.intellij.util.ProcessingContext;
import com.jetbrains.python.psi.AccessDirection;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyQualifiedExpression;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import org.jetbrains.annotations.NotNull;
@@ -14,23 +11,21 @@ import java.util.Collections;
import java.util.List;
/**
* Type of a particular function that is represented as a {@link PyFunction} in the PSI tree.
*
* TODO: Maybe this class should extend PyClassType and have a Python mock class for <code>type 'function'</code> in the __builtins__.
* Type of a particular function that is represented as a {@link Callable} in the PSI tree.
*
* @author vlan
*/
public class PyFunctionType implements PyCallableType {
@NotNull private final PyFunction myFunction;
@NotNull private final Callable myCallable;
public PyFunctionType(@NotNull PyFunction function) {
myFunction = function;
public PyFunctionType(@NotNull Callable callable) {
myCallable = callable;
}
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
return myFunction.getReturnType(context, callSite);
return myCallable.getReturnType(context, callSite);
}
@Override
@@ -61,7 +56,7 @@ public class PyFunctionType implements PyCallableType {
}
@NotNull
public PyFunction getFunction() {
return myFunction;
public Callable getCallable() {
return myCallable;
}
}
@@ -269,7 +269,7 @@ public class PyTypeChecker {
}
@NotNull
public static Map<PyGenericType, PyType> collectCallGenerics(@NotNull PyFunction function, @Nullable PyExpression receiver,
public static Map<PyGenericType, PyType> collectCallGenerics(@NotNull Callable callable, @Nullable PyExpression receiver,
@NotNull TypeEvalContext context) {
final Map<PyGenericType, PyType> substitutions = new LinkedHashMap<PyGenericType, PyType>();
// Collect generic params of object type
@@ -279,7 +279,7 @@ public class PyTypeChecker {
for (PyGenericType t : generics) {
substitutions.put(t, t);
}
final PyClass cls = function.getContainingClass();
final PyClass cls = (callable instanceof PyFunction) ? ((PyFunction)callable).getContainingClass() : null;
if (cls != null) {
final PyFunction init = cls.findInitOrNew(true);
// Unify generics in constructor
@@ -346,17 +346,17 @@ public class PyTypeChecker {
if (!(type instanceof PyFunctionType)) {
return null;
}
final PyFunction function = ((PyFunctionType)type).getFunction();
final Callable callable = ((PyFunctionType)type).getCallable();
final boolean isRight = PyNames.isRightOperatorName(typedElement.getName());
final PyExpression arg = isRight ? expr.getLeftExpression() : expr.getRightExpression();
final PyExpression receiver = isRight ? expr.getRightExpression() : expr.getLeftExpression();
final PyParameter[] parameters = function.getParameterList().getParameters();
final PyParameter[] parameters = callable.getParameterList().getParameters();
if (parameters.length >= 2) {
final PyNamedParameter param = parameters[1].getAsNamed();
if (arg != null && param != null) {
final Map<PyExpression, PyNamedParameter> arguments = new LinkedHashMap<PyExpression, PyNamedParameter>();
arguments.put(arg, param);
final AnalyzeCallResults results = new AnalyzeCallResults(function, receiver, arguments);
final AnalyzeCallResults results = new AnalyzeCallResults(callable, receiver, arguments);
if (firstResults == null) {
firstResults = results;
}
@@ -382,8 +382,8 @@ public class PyTypeChecker {
if (resolved instanceof PyTypedElement) {
final PyType type = ((PyTypedElement)resolved).getType(context);
if (type instanceof PyFunctionType) {
final PyFunction function = ((PyFunctionType)type).getFunction();
final PyParameter[] parameters = function.getParameterList().getParameters();
final Callable callable = ((PyFunctionType)type).getCallable();
final PyParameter[] parameters = callable.getParameterList().getParameters();
if (parameters.length == 2) {
final PyNamedParameter param = parameters[1].getAsNamed();
if (param != null) {
@@ -391,7 +391,7 @@ public class PyTypeChecker {
final PyExpression arg = expr.getIndexExpression();
if (arg != null) {
arguments.put(arg, param);
return new AnalyzeCallResults(function, expr.getOperand(), arguments);
return new AnalyzeCallResults(callable, expr.getOperand(), arguments);
}
}
}
@@ -423,20 +423,20 @@ public class PyTypeChecker {
}
public static class AnalyzeCallResults {
@NotNull private final PyFunction myFunction;
@NotNull private final Callable myCallable;
@Nullable private final PyExpression myReceiver;
@NotNull private final Map<PyExpression, PyNamedParameter> myArguments;
public AnalyzeCallResults(@NotNull PyFunction function, @Nullable PyExpression receiver,
public AnalyzeCallResults(@NotNull Callable callable, @Nullable PyExpression receiver,
@NotNull Map<PyExpression, PyNamedParameter> arguments) {
myFunction = function;
myCallable = callable;
myReceiver = receiver;
myArguments = arguments;
}
@NotNull
public PyFunction getFunction() {
return myFunction;
public Callable getCallable() {
return myCallable;
}
@Nullable
@@ -11,6 +11,7 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.remotesdk.RemoteCredentials;
import com.intellij.remotesdk.RemoteInterpreterException;
import com.intellij.remotesdk.RemoteSdkData;
import com.intellij.remotesdk.RemoteSshProcess;
@@ -6,9 +6,9 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.remotesdk.RemoteCredentials;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.remotesdk.RemoteSdkData;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -204,6 +204,6 @@ public class PySdkUtil {
}
public static boolean isRemote(@Nullable Sdk sdk) {
return sdk != null && sdk.getSdkAdditionalData() instanceof RemoteSdkData;
return sdk != null && sdk.getSdkAdditionalData() instanceof RemoteCredentials;
}
}
@@ -0,0 +1,15 @@
class D(object):
def __init__(self, attribute, value):
pass
def __call__(self, cls):
return cls
@D("value", 42)
class C(object):
pass
a = C()
print(a.value)
@@ -0,0 +1,23 @@
import float
from foo import float
from bar import baz as <warning descr="Shadows a built-in with the same name">float</warning>
def test1(x, <warning descr="Shadows a built-in with the same name">len</warning>, <warning descr="Shadows a built-in with the same name">file</warning>=None):
foo = 2
<warning descr="Shadows a built-in with the same name">list</warning> = []
for <warning descr="Shadows a built-in with the same name">int</warning> in range(10):
print(int)
<warning descr="Shadows a built-in with the same name">range</warning> = []
return [int for <warning descr="Shadows a built-in with the same name">int</warning> in range(10)]
def <warning descr="Shadows a built-in with the same name">list</warning>():
pass
class <warning descr="Shadows a built-in with the same name">list</warning>(object):
def foo(self):
pass
def list(self):
pass
@@ -306,4 +306,9 @@ public class PythonInspectionsTest extends PyTestCase {
public void testPyDecoratorInspection() { //PY-3348
doHighlightingTest(PyDecoratorInspection.class);
}
// PY-5807
public void testPyShadowingBuiltinsInspection() {
doHighlightingTest(PyShadowingBuiltinsInspection.class);
}
}
@@ -59,6 +59,11 @@ public class PyCallingNonCallableInspectionTest extends PyTestCase {
doTest();
}
// PY-5905
public void testCallableClassDecorator() {
doTest();
}
private void doTest() {
setLanguageLevel(LanguageLevel.PYTHON27);
try {