mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Update PyCompatibilityInspection to correctly process long in Python 2.
The reason of update is that `long` is described as `long = int` in pyi-stubs.
This commit is contained in:
@@ -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}
|
||||
*/
|
||||
|
||||
+5
-5
@@ -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<PsiEleme
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
@@ -125,9 +125,9 @@ public class DocStringTypeReference extends PsiPolyVariantReferenceBase<PsiEleme
|
||||
@NotNull
|
||||
public List<Object> collectTypeVariants() {
|
||||
final PsiFile file = myElement.getContainingFile();
|
||||
final ArrayList<Object>
|
||||
variants = Lists.newArrayList("str", "int", "basestring", "bool", "buffer", "bytearray", "complex", "dict",
|
||||
"tuple", "enumerate", "file", "float", "frozenset", "list", "long", "set", "object");
|
||||
final List<Object> 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<PyFromImportStatement> fromImports = ((PyFile)file).getFromImports();
|
||||
|
||||
@@ -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<PyFunction> 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
|
||||
|
||||
@@ -448,8 +448,12 @@ public class PyStringFormatInspection extends PyInspection {
|
||||
}
|
||||
|
||||
private static class NewStyleInspection {
|
||||
private static final List<String> CHECKED_TYPES = Arrays.asList("str", "int", "long", "float", "complex", "None");
|
||||
private static final List<String> NUMERIC_TYPES = Arrays.asList("int", "long", "float", "complex");
|
||||
|
||||
private static final List<String> CHECKED_TYPES =
|
||||
Arrays.asList(PyNames.TYPE_STR, PyNames.TYPE_INT, PyNames.TYPE_LONG, "float", "complex", "None");
|
||||
|
||||
private static final List<String> NUMERIC_TYPES = Arrays.asList(PyNames.TYPE_INT, PyNames.TYPE_LONG, "float", "complex");
|
||||
|
||||
private static final ImmutableMap<Character, String> NEW_STYLE_FORMAT_CONVERSIONS = ImmutableMap.<Character, String>builder()
|
||||
.put('s', "str or None")
|
||||
.put('b', "int")
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<warning descr="Python version 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6 do not have type long. Use int instead.">long("abc")</warning>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user