mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-07 22:09:38 +07:00
Restored None, False, True as non-keywords (reserved words) in PY2 (PY-23305, PY-23364)
Typeshed doesn't contain the definitions for them in __builtins__.pyi so we have to provide types and detect the builtin status for these words as a special case.
This commit is contained in:
committed by
Andrey Vlasovskikh
parent
859ed8fb1c
commit
91a45bf7ed
@@ -82,6 +82,21 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context) {
|
||||
if (!referenceExpression.isQualified()) {
|
||||
final String name = referenceExpression.getReferencedName();
|
||||
if (PyNames.NONE.equals(name)) {
|
||||
return PyNoneType.INSTANCE;
|
||||
}
|
||||
else if (PyNames.FALSE.equals(name) || PyNames.TRUE.equals(name)) {
|
||||
return PyBuiltinCache.getInstance(referenceExpression).getBoolType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyType getBaseStringType(@NotNull PsiElement referenceTarget) {
|
||||
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(referenceTarget);
|
||||
|
||||
@@ -149,18 +149,23 @@ public class PyArgumentEqualDefaultInspection extends PyInspection {
|
||||
if (((PyStringLiteralExpression)key).getStringValue().equals(((PyStringLiteralExpression)defaultValue).getStringValue()))
|
||||
return true;
|
||||
}
|
||||
else if (key instanceof PyReferenceExpression && PyUtil.isPy2ReservedWord((PyReferenceExpression)key) &&
|
||||
key.getText().equals(defaultValue.getText())) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
PsiReference keyRef = key instanceof PyReferenceExpression
|
||||
? ((PyReferenceExpression) key).getReference(getResolveContext())
|
||||
PsiReference keyRef = key instanceof PyReferenceExpression
|
||||
? ((PyReferenceExpression)key).getReference(getResolveContext())
|
||||
: key.getReference();
|
||||
PsiReference defRef = defaultValue instanceof PyReferenceExpression
|
||||
? ((PyReferenceExpression) defaultValue).getReference(getResolveContext())
|
||||
? ((PyReferenceExpression)defaultValue).getReference(getResolveContext())
|
||||
: defaultValue.getReference();
|
||||
if (keyRef != null && defRef != null) {
|
||||
PsiElement keyResolve = keyRef.resolve();
|
||||
PsiElement defResolve = defRef.resolve();
|
||||
if (keyResolve != null && keyResolve.equals(defResolve))
|
||||
if (keyResolve != null && keyResolve.equals(defResolve)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.codeInsight.stdlib.PyNamedTupleType;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.psi.types.PyNoneType;
|
||||
import com.jetbrains.python.psi.types.PyTupleType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
@@ -112,6 +113,9 @@ public class PyTupleAssignmentBalanceInspection extends PyInspection {
|
||||
else if (assignedType instanceof PyNamedTupleType) {
|
||||
return ((PyNamedTupleType)assignedType).getElementCount();
|
||||
}
|
||||
else if (assignedType instanceof PyNoneType) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -69,10 +69,6 @@ public class PythonHighlightingLexer extends PythonLexer {
|
||||
if (tokenType == PyTokenTypes.IDENTIFIER) {
|
||||
final String tokenText = getTokenText();
|
||||
|
||||
if (tokenText.equals("None")) return PyTokenTypes.NONE_KEYWORD;
|
||||
if (tokenText.equals("True")) return PyTokenTypes.TRUE_KEYWORD;
|
||||
if (tokenText.equals("False")) return PyTokenTypes.FALSE_KEYWORD;
|
||||
|
||||
if (myLanguageLevel.hasWithStatement()) {
|
||||
if (tokenText.equals("with")) return PyTokenTypes.WITH_KEYWORD;
|
||||
if (tokenText.equals("as")) return PyTokenTypes.AS_KEYWORD;
|
||||
@@ -83,6 +79,9 @@ public class PythonHighlightingLexer extends PythonLexer {
|
||||
}
|
||||
|
||||
if (myLanguageLevel.isPy3K()) {
|
||||
if (tokenText.equals("None")) return PyTokenTypes.NONE_KEYWORD;
|
||||
if (tokenText.equals("True")) return PyTokenTypes.TRUE_KEYWORD;
|
||||
if (tokenText.equals("False")) return PyTokenTypes.FALSE_KEYWORD;
|
||||
if (tokenText.equals("nonlocal")) return PyTokenTypes.NONLOCAL_KEYWORD;
|
||||
if (tokenText.equals("__debug__")) return PyTokenTypes.DEBUG_KEYWORD;
|
||||
}
|
||||
|
||||
@@ -927,16 +927,16 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
|
||||
isWordAtPosition(text, start, end, TOK_PRINT)) {
|
||||
return PyTokenTypes.PRINT_KEYWORD;
|
||||
}
|
||||
else if (source == PyTokenTypes.IDENTIFIER && isWordAtPosition(text, start, end, TOK_NONE)) {
|
||||
return PyTokenTypes.NONE_KEYWORD;
|
||||
}
|
||||
else if (source == PyTokenTypes.IDENTIFIER && isWordAtPosition(text, start, end, TOK_TRUE)) {
|
||||
return PyTokenTypes.TRUE_KEYWORD;
|
||||
}
|
||||
else if (source == PyTokenTypes.IDENTIFIER && isWordAtPosition(text, start, end, TOK_FALSE)) {
|
||||
return PyTokenTypes.FALSE_KEYWORD;
|
||||
}
|
||||
else if (myContext.getLanguageLevel().isPy3K() && source == PyTokenTypes.IDENTIFIER) {
|
||||
if (isWordAtPosition(text, start, end, TOK_NONE)) {
|
||||
return PyTokenTypes.NONE_KEYWORD;
|
||||
}
|
||||
if (isWordAtPosition(text, start, end, TOK_TRUE)) {
|
||||
return PyTokenTypes.TRUE_KEYWORD;
|
||||
}
|
||||
if (isWordAtPosition(text, start, end, TOK_FALSE)) {
|
||||
return PyTokenTypes.FALSE_KEYWORD;
|
||||
}
|
||||
if (isWordAtPosition(text, start, end, TOK_DEBUG)) {
|
||||
return PyTokenTypes.DEBUG_KEYWORD;
|
||||
}
|
||||
|
||||
@@ -910,6 +910,18 @@ public class PyUtil {
|
||||
return as(PyPsiUtils.getPrevNonWhitespaceSibling(statementList), PsiComment.class);
|
||||
}
|
||||
|
||||
public static boolean isPy2ReservedWord(@NotNull PyReferenceExpression node) {
|
||||
if (LanguageLevel.forElement(node).isOlderThan(LanguageLevel.PYTHON30)) {
|
||||
if (!node.isQualified()) {
|
||||
final String name = node.getName();
|
||||
if (PyNames.NONE.equals(name) || PyNames.FALSE.equals(name) || PyNames.TRUE.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the document from {@link PsiDocumentManager} using the anchor PSI element and pass it to the consumer function
|
||||
* first releasing it from pending PSI modifications it with {@link PsiDocumentManager#doPostponedOperationsAndUnblockDocument(Document)}
|
||||
|
||||
@@ -228,10 +228,6 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
try {
|
||||
final boolean qualified = isQualified();
|
||||
|
||||
if (!qualified && PyNames.NONE.equals(getReferencedName())) {
|
||||
return PyNoneType.INSTANCE;
|
||||
}
|
||||
|
||||
final PyType providedType = getTypeFromProviders(context);
|
||||
if (providedType != null) {
|
||||
return providedType;
|
||||
|
||||
@@ -37,7 +37,10 @@ public class PyBuiltinAnnotator extends PyAnnotator {
|
||||
final String name = node.getName();
|
||||
if (name == null) return;
|
||||
final boolean highlightedAsAttribute = highlightAsAttribute(node, name);
|
||||
if (!highlightedAsAttribute && PyBuiltinCache.isInBuiltins(node)) {
|
||||
if (highlightedAsAttribute) {
|
||||
return;
|
||||
}
|
||||
if (PyBuiltinCache.isInBuiltins(node) || PyUtil.isPy2ReservedWord(node)) {
|
||||
final Annotation ann;
|
||||
final PsiElement parent = node.getParent();
|
||||
if (parent instanceof PyDecorator) {
|
||||
|
||||
@@ -14,4 +14,4 @@ class <info descr="null" type="INFORMATION" foreground="0x0000ff" background="0x
|
||||
pass
|
||||
|
||||
def <info descr="null" type="INFORMATION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">__made_up__</info>(<info descr="null">self</info>):
|
||||
return None
|
||||
return <info type="INFORMATION">None</info>
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
def <info descr="null" type="INFORMATION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">foo</info>():
|
||||
def <info descr="null" type="INFORMATION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">a</info>():
|
||||
yield 1
|
||||
return False
|
||||
return <info type="INFORMATION">False</info>
|
||||
|
||||
@@ -13,8 +13,8 @@ PyFile:BlockWithoutColon.py
|
||||
PyWhilePart
|
||||
PsiElement(Py:WHILE_KEYWORD)('while')
|
||||
PsiWhiteSpace(' ')
|
||||
PyBoolLiteralExpression
|
||||
PsiElement(Py:TRUE_KEYWORD)('True')
|
||||
PyReferenceExpression: True
|
||||
PsiElement(Py:IDENTIFIER)('True')
|
||||
PsiErrorElement:Colon expected
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
|
||||
@@ -12,8 +12,8 @@ PyFile:ErrorInParameterList.py
|
||||
PyNamedParameter('filds')
|
||||
PsiElement(Py:IDENTIFIER)('filds')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PyNoneLiteralExpression
|
||||
PsiElement(Py:NONE_KEYWORD)('None')
|
||||
PyReferenceExpression: None
|
||||
PsiElement(Py:IDENTIFIER)('None')
|
||||
PsiElement(Py:COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:formal parameter name expected
|
||||
|
||||
@@ -19,8 +19,8 @@ PyFile:LambdaComprehension.py
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyBoolLiteralExpression
|
||||
PsiElement(Py:TRUE_KEYWORD)('True')
|
||||
PyReferenceExpression: True
|
||||
PsiElement(Py:IDENTIFIER)('True')
|
||||
PsiElement(Py:COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PyLambdaExpression
|
||||
@@ -29,8 +29,8 @@ PyFile:LambdaComprehension.py
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyBoolLiteralExpression
|
||||
PsiElement(Py:FALSE_KEYWORD)('False')
|
||||
PyReferenceExpression: False
|
||||
PsiElement(Py:IDENTIFIER)('False')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IF_KEYWORD)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
|
||||
@@ -14,8 +14,8 @@ PyFile:NotClosedSlice.py
|
||||
PyIfPartIf
|
||||
PsiElement(Py:IF_KEYWORD)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PyBoolLiteralExpression
|
||||
PsiElement(Py:TRUE_KEYWORD)('True')
|
||||
PyReferenceExpression: True
|
||||
PsiElement(Py:IDENTIFIER)('True')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace('\n ')
|
||||
PyStatementList
|
||||
|
||||
@@ -3,8 +3,8 @@ PyFile:ResetAfterSemicolon.py
|
||||
PyIfPartIf
|
||||
PsiElement(Py:IF_KEYWORD)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PyBoolLiteralExpression
|
||||
PsiElement(Py:TRUE_KEYWORD)('True')
|
||||
PyReferenceExpression: True
|
||||
PsiElement(Py:IDENTIFIER)('True')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace('\n ')
|
||||
PyStatementList
|
||||
|
||||
Reference in New Issue
Block a user