diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java index 4d36979ca649..3421155b6981 100644 --- a/python/psi-api/src/com/jetbrains/python/PyNames.java +++ b/python/psi-api/src/com/jetbrains/python/PyNames.java @@ -38,6 +38,7 @@ public class PyNames { * int type */ public static final String TYPE_INT = "int"; + public static final String TYPE_LONG = "long"; /** * unicode string type (see {@link #TYPE_STRING_TYPES} */ diff --git a/python/src/com/jetbrains/python/documentation/docstrings/DocStringTypeReference.java b/python/src/com/jetbrains/python/documentation/docstrings/DocStringTypeReference.java index 548b87d906f7..50d0865d9400 100644 --- a/python/src/com/jetbrains/python/documentation/docstrings/DocStringTypeReference.java +++ b/python/src/com/jetbrains/python/documentation/docstrings/DocStringTypeReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -33,7 +33,6 @@ import com.jetbrains.python.psi.types.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; /** @@ -72,6 +71,7 @@ public class DocStringTypeReference extends PsiPolyVariantReferenceBase collectTypeVariants() { final PsiFile file = myElement.getContainingFile(); - final ArrayList - variants = Lists.newArrayList("str", "int", "basestring", "bool", "buffer", "bytearray", "complex", "dict", - "tuple", "enumerate", "file", "float", "frozenset", "list", "long", "set", "object"); + final List variants = + Lists.newArrayList(PyNames.TYPE_STR, PyNames.TYPE_INT, "basestring", "bool", "buffer", "bytearray", "complex", "dict", + "tuple", "enumerate", "file", "float", "frozenset", "list", PyNames.TYPE_LONG, "set", "object"); if (file instanceof PyFile) { variants.addAll(((PyFile)file).getTopLevelClasses()); final List fromImports = ((PyFile)file).getFromImports(); diff --git a/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java b/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java index 3d260963e467..772c3b330fd2 100644 --- a/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -169,15 +169,14 @@ public class PyCompatibilityInspection extends PyInspection { public void visitPyCallExpression(PyCallExpression node) { super.visitPyCallExpression(node); - final Optional optionalFunction = Optional + final PsiElement resolvedCallee = Optional .ofNullable(node.getCallee()) .map(PyExpression::getReference) .map(PsiReference::resolve) - .filter(PyFunction.class::isInstance) - .map(PyFunction.class::cast); + .orElse(null); - if (optionalFunction.isPresent()) { - final PyFunction function = optionalFunction.get(); + if (resolvedCallee instanceof PyFunction) { + final PyFunction function = (PyFunction)resolvedCallee; final PyClass containingClass = function.getContainingClass(); final String originalFunctionName = function.getName(); @@ -208,6 +207,18 @@ public class PyCompatibilityInspection extends PyInspection { null); } } + else if (resolvedCallee instanceof PyTargetExpression) { + final PyTargetExpression target = (PyTargetExpression)resolvedCallee; + + if (!target.isQualified() && + PyNames.TYPE_LONG.equals(target.getName()) && + PyBuiltinCache.getInstance(resolvedCallee).isBuiltin(resolvedCallee)) { + registerForAllMatchingVersions(level -> UnsupportedFeaturesUtil.BUILTINS.get(level).contains(PyNames.TYPE_LONG), + " not have type long. Use int instead.", + node, + null); + } + } } @Override diff --git a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java index 6c77a59edcdf..9501fe7f77eb 100644 --- a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java @@ -448,8 +448,12 @@ public class PyStringFormatInspection extends PyInspection { } private static class NewStyleInspection { - private static final List CHECKED_TYPES = Arrays.asList("str", "int", "long", "float", "complex", "None"); - private static final List NUMERIC_TYPES = Arrays.asList("int", "long", "float", "complex"); + + private static final List CHECKED_TYPES = + Arrays.asList(PyNames.TYPE_STR, PyNames.TYPE_INT, PyNames.TYPE_LONG, "float", "complex", "None"); + + private static final List NUMERIC_TYPES = Arrays.asList(PyNames.TYPE_INT, PyNames.TYPE_LONG, "float", "complex"); + private static final ImmutableMap NEW_STYLE_FORMAT_CONVERSIONS = ImmutableMap.builder() .put('s', "str or None") .put('b', "int") diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index f449719537c1..a0fafcbbc6fd 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -347,14 +347,14 @@ public class PyTypeChecker { final String superName = expected.getName(); final String subName = actual.getName(); final boolean subIsBool = "bool".equals(subName); - final boolean subIsInt = "int".equals(subName); - final boolean subIsLong = "long".equals(subName); + final boolean subIsInt = PyNames.TYPE_INT.equals(subName); + final boolean subIsLong = PyNames.TYPE_LONG.equals(subName); final boolean subIsFloat = "float".equals(subName); final boolean subIsComplex = "complex".equals(subName); if (superName == null || subName == null || superName.equals(subName) || - ("int".equals(superName) && subIsBool) || - (("long".equals(superName) || PyNames.ABC_INTEGRAL.equals(superName)) && (subIsBool || subIsInt)) || + (PyNames.TYPE_INT.equals(superName) && subIsBool) || + ((PyNames.TYPE_LONG.equals(superName) || PyNames.ABC_INTEGRAL.equals(superName)) && (subIsBool || subIsInt)) || (("float".equals(superName) || PyNames.ABC_REAL.equals(superName)) && (subIsBool || subIsInt || subIsLong)) || (("complex".equals(superName) || PyNames.ABC_COMPLEX.equals(superName)) && (subIsBool || subIsInt || subIsLong || subIsFloat)) || (PyNames.ABC_NUMBER.equals(superName) && (subIsBool || subIsInt || subIsLong || subIsFloat || subIsComplex))) { diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java index 1499e771c542..8308efd6bd21 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java @@ -500,7 +500,7 @@ public class PyTypeParser { else if (PyNames.NONE.equals(name)) { return new ParseResult(PyNoneType.INSTANCE, range); } - else if ("integer".equals(name) || "long".equals(name)) { + else if ("integer".equals(name) || PyNames.TYPE_LONG.equals(name)) { final PyClassType type = builtinCache.getIntType(); return type != null ? new ParseResult(type, range) : EMPTY_RESULT; } @@ -516,7 +516,7 @@ public class PyTypeParser { final PyClassType type = builtinCache.getBytesType(LanguageLevel.forElement(myAnchor)); return type != null ? new ParseResult(type, range) : EMPTY_RESULT; } - else if ("unicode".equals(name)) { + else if (PyNames.TYPE_UNICODE.equals(name)) { final PyClassType type = builtinCache.getUnicodeType(LanguageLevel.forElement(myAnchor)); return type != null ? new ParseResult(type, range) : EMPTY_RESULT; } diff --git a/python/testData/inspections/PyCompatibilityInspection/builtinLong.py b/python/testData/inspections/PyCompatibilityInspection/builtinLong.py new file mode 100644 index 000000000000..8b5cd81346c2 --- /dev/null +++ b/python/testData/inspections/PyCompatibilityInspection/builtinLong.py @@ -0,0 +1 @@ +long("abc") \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java index 50e7d9825960..d5a2445118ed 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -229,6 +229,10 @@ public class PyCompatibilityInspectionTest extends PyTestCase { doTest(); } + public void testBuiltinLong() { + doTest(); + } + private void doTest(@NotNull LanguageLevel level) { runWithLanguageLevel(level, this::doTest); }