True, False and None are keywords in Python 3

This commit is contained in:
Dmitry Jemerov
2010-01-21 16:57:37 +03:00
parent ba973874a1
commit 162fdefd5f
13 changed files with 113 additions and 4 deletions

View File

@@ -75,6 +75,8 @@ public interface PyElementTypes {
PyElementType FLOAT_LITERAL_EXPRESSION = new PyElementType("FLOAT_LITERAL_EXPRESSION", PyNumericLiteralExpressionImpl.class);
PyElementType IMAGINARY_LITERAL_EXPRESSION = new PyElementType("IMAGINARY_LITERAL_EXPRESSION", PyNumericLiteralExpressionImpl.class);
PyElementType STRING_LITERAL_EXPRESSION = new PyElementType("STRING_LITERAL_EXPRESSION", PyStringLiteralExpressionImpl.class);
PyElementType NONE_LITERAL_EXPRESSION = new PyElementType("NONE_LITERAL_EXPRESSION", PyNoneLiteralExpressionImpl.class);
PyElementType BOOL_LITERAL_EXPRESSION = new PyElementType("BOOL_LITERAL_EXPRESSION", PyBoolLiteralExpressionImpl.class);
PyElementType PARENTHESIZED_EXPRESSION = new PyElementType("PARENTHESIZED_EXPRESSION", PyParenthesizedExpressionImpl.class);
PyElementType SUBSCRIPTION_EXPRESSION = new PyElementType("SUBSCRIPTION_EXPRESSION", PySubscriptionExpressionImpl.class);
PyElementType SLICE_EXPRESSION = new PyElementType("SLICE_EXPRESSION", PySliceExpressionImpl.class);

View File

@@ -52,6 +52,11 @@ public class PyTokenTypes {
public static final PyElementType WHILE_KEYWORD = new PyElementType("WHILE_KEYWORD");
public static final PyElementType YIELD_KEYWORD = new PyElementType("YIELD_KEYWORD");
// new keywords in Python 3
public static final PyElementType NONE_KEYWORD = new PyElementType("NONE_KEYWORD");
public static final PyElementType TRUE_KEYWORD = new PyElementType("TRUE_KEYWORD");
public static final PyElementType FALSE_KEYWORD = new PyElementType("FALSE_KEYWORD");
public static final TokenSet KEYWORDS = TokenSet.create(
AND_KEYWORD, AS_KEYWORD, ASSERT_KEYWORD, BREAK_KEYWORD, CLASS_KEYWORD,
CONTINUE_KEYWORD, DEF_KEYWORD, DEL_KEYWORD, ELIF_KEYWORD, ELSE_KEYWORD,
@@ -60,7 +65,8 @@ public class PyTokenTypes {
GLOBAL_KEYWORD, IF_KEYWORD, IMPORT_KEYWORD, IN_KEYWORD, IS_KEYWORD,
LAMBDA_KEYWORD, NOT_KEYWORD, OR_KEYWORD, PASS_KEYWORD, PRINT_KEYWORD,
RAISE_KEYWORD, RETURN_KEYWORD, TRY_KEYWORD, WITH_KEYWORD, WHILE_KEYWORD,
YIELD_KEYWORD);
YIELD_KEYWORD,
NONE_KEYWORD, TRUE_KEYWORD, FALSE_KEYWORD);
public static final PyElementType INTEGER_LITERAL = new PyElementType("INTEGER_LITERAL");
public static final PyElementType FLOAT_LITERAL = new PyElementType("FLOAT_LITERAL");

View File

@@ -25,6 +25,12 @@ public class PythonHighlightingLexer extends PythonLexer {
final String tokenText = getTokenText();
if (tokenText.equals("print")) return PyTokenTypes.PRINT_KEYWORD;
}
if (myLanguageLevel.isPy3K()) {
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;
}
return super.getTokenType();
}
}

View File

@@ -41,6 +41,14 @@ public class ExpressionParsing extends Parsing {
buildTokenElement(PyElementTypes.IMAGINARY_LITERAL_EXPRESSION, builder);
return true;
}
else if (firstToken == PyTokenTypes.NONE_KEYWORD) {
buildTokenElement(PyElementTypes.NONE_LITERAL_EXPRESSION, builder);
return true;
}
else if (firstToken == PyTokenTypes.TRUE_KEYWORD || firstToken == PyTokenTypes.FALSE_KEYWORD) {
buildTokenElement(PyElementTypes.BOOL_LITERAL_EXPRESSION, builder);
return true;
}
else if (firstToken == PyTokenTypes.STRING_LITERAL) {
final PsiBuilder.Marker marker = builder.mark();
while (builder.getTokenType() == PyTokenTypes.STRING_LITERAL) {

View File

@@ -26,6 +26,9 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
@NonNls protected static final String TOK_WITH = "with";
@NonNls protected static final String TOK_AS = "as";
@NonNls protected static final String TOK_PRINT = "print";
@NonNls protected static final String TOK_NONE = "None";
@NonNls protected static final String TOK_TRUE = "True";
@NonNls protected static final String TOK_FALSE = "False";
protected enum Phase {NONE, FROM, FUTURE, IMPORT} // 'from __future__ import' phase
private Phase myFutureImportPhase = Phase.NONE;
@@ -745,6 +748,17 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
isWordAtPosition(text, start, end, TOK_PRINT)) {
return PyTokenTypes.PRINT_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;
}
}
return source;
}

View File

@@ -0,0 +1,7 @@
package com.jetbrains.python.psi;
/**
* @author yole
*/
public interface PyBoolLiteralExpression extends PyLiteralExpression {
}

View File

@@ -0,0 +1,7 @@
package com.jetbrains.python.psi;
/**
* @author yole
*/
public interface PyNoneLiteralExpression extends PyLiteralExpression {
}

View File

@@ -0,0 +1,19 @@
package com.jetbrains.python.psi.impl;
import com.intellij.lang.ASTNode;
import com.jetbrains.python.psi.PyBoolLiteralExpression;
import com.jetbrains.python.psi.types.PyType;
/**
* @author yole
*/
public class PyBoolLiteralExpressionImpl extends PyElementImpl implements PyBoolLiteralExpression {
public PyBoolLiteralExpressionImpl(ASTNode astNode) {
super(astNode);
}
public PyType getType() {
// TODO
return null;
}
}

View File

@@ -0,0 +1,19 @@
package com.jetbrains.python.psi.impl;
import com.intellij.lang.ASTNode;
import com.jetbrains.python.psi.PyNoneLiteralExpression;
import com.jetbrains.python.psi.types.PyNoneType;
import com.jetbrains.python.psi.types.PyType;
/**
* @author yole
*/
public class PyNoneLiteralExpressionImpl extends PyElementImpl implements PyNoneLiteralExpression {
public PyNoneLiteralExpressionImpl(ASTNode astNode) {
super(astNode);
}
public PyType getType() {
return PyNoneType.INSTANCE;
}
}

View File

@@ -20,8 +20,8 @@ PyFile:KeywordOnlyArgument.py
PyNamedParameter('key')
PsiElement(Py:IDENTIFIER)('key')
PsiElement(Py:EQ)('=')
PyReferenceExpression: None
PsiElement(Py:IDENTIFIER)('None')
PyNoneLiteralExpression
PsiElement(Py:NONE_KEYWORD)('None')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')

View File

@@ -0,0 +1,3 @@
None
True
False

View File

@@ -0,0 +1,12 @@
PyFile:Py3KKeywords.py
PyExpressionStatement
PyNoneLiteralExpression
PsiElement(Py:NONE_KEYWORD)('None')
PsiWhiteSpace('\n')
PyExpressionStatement
PyBoolLiteralExpression
PsiElement(Py:TRUE_KEYWORD)('True')
PsiWhiteSpace('\n')
PyExpressionStatement
PyBoolLiteralExpression
PsiElement(Py:FALSE_KEYWORD)('False')

View File

@@ -1,6 +1,7 @@
package com.jetbrains.python;
import com.intellij.testFramework.ParsingTestCase;
import com.intellij.testFramework.TestDataPath;
import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
@@ -8,6 +9,7 @@ import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
/**
* @author yole
*/
@TestDataPath("$CONTENT_ROOT/../testData/psi/")
public class PythonParsingTest extends ParsingTestCase {
public PythonParsingTest() {
super("", "py");
@@ -97,7 +99,7 @@ public class PythonParsingTest extends ParsingTestCase {
}
public void testWithStatement26() throws Exception {
doTest(LanguageLevel.PYTHON26);
doTest(LanguageLevel.PYTHON26);
}
public void testPrintAsFunction26() throws Exception {
@@ -120,6 +122,10 @@ public class PythonParsingTest extends ParsingTestCase {
doTest(LanguageLevel.PYTHON30);
}
public void testPy3KKeywords() throws Exception {
doTest(LanguageLevel.PYTHON30);
}
public void doTest() throws Exception {
doTest(LanguageLevel.PYTHON25);
}