Minor fixes in parser

This commit is contained in:
Ivan Kochurkin
2022-08-01 01:14:02 +02:00
committed by teamcity
parent 1d73d4cfbf
commit daeb41b411
10 changed files with 80 additions and 74 deletions
@@ -76,6 +76,7 @@ public interface KDocTokens {
KDocToken MARKDOWN_ESCAPED_CHAR = new KDocToken("KDOC_MARKDOWN_ESCAPED_CHAR", MARKDOWN_ESCAPED_CHAR_Id);
KDocToken MARKDOWN_INLINE_LINK = new KDocToken("KDOC_MARKDOWN_INLINE_LINK", MARKDOWN_INLINE_LINK_Id);
@SuppressWarnings("unused")
TokenSet KDOC_HIGHLIGHT_TOKENS = TokenSet.create(START, END, LEADING_ASTERISK, TEXT, CODE_BLOCK_TEXT, MARKDOWN_LINK, MARKDOWN_ESCAPED_CHAR, MARKDOWN_INLINE_LINK);
TokenSet CONTENT_TOKENS = TokenSet.create(TEXT, CODE_BLOCK_TEXT, TAG_NAME, MARKDOWN_LINK, MARKDOWN_ESCAPED_CHAR, MARKDOWN_INLINE_LINK);
}
@@ -78,6 +78,16 @@ import static org.jetbrains.kotlin.lexer.KtTokens.*;
}
protected boolean expect(KtToken expectation, String message, TokenSet recoverySet) {
if (expect(expectation)) {
return true;
}
errorWithRecovery(message, recoverySet);
return false;
}
protected boolean expect(KtToken expectation) {
if (at(expectation)) {
advance(); // expectation
return true;
@@ -87,8 +97,6 @@ import static org.jetbrains.kotlin.lexer.KtTokens.*;
advance();
}
errorWithRecovery(message, recoverySet);
return false;
}
@@ -129,6 +129,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
LBRACKET // Collection literal expression
);
@SuppressWarnings("WeakerAccess")
public static final TokenSet STATEMENT_FIRST = TokenSet.orSet(
EXPRESSION_FIRST,
TokenSet.create(
@@ -202,7 +203,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
;
static {
Precedence[] values = Precedence.values();
Precedence[] values = values();
for (Precedence precedence : values) {
int ordinal = precedence.ordinal();
precedence.higher = ordinal > 0 ? values[ordinal - 1] : null;
@@ -238,7 +239,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
}
}
public static final TokenSet ALLOW_NEWLINE_OPERATIONS = TokenSet.create(
private static final TokenSet ALLOW_NEWLINE_OPERATIONS = TokenSet.create(
DOT, SAFE_ACCESS,
COLON, AS_KEYWORD, AS_SAFE,
ELVIS,
@@ -255,7 +256,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
for (Precedence precedence : values) {
operations.addAll(Arrays.asList(precedence.getOperations().getTypes()));
}
ALL_OPERATIONS = TokenSet.create(operations.toArray(new IElementType[operations.size()]));
ALL_OPERATIONS = TokenSet.create(operations.toArray(new IElementType[0]));
}
static {
@@ -862,7 +863,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
advanceAt(LPAR);
PsiBuilder.Marker atWhenStart = mark();
myKotlinParsing.parseAnnotationsList(DEFAULT, EQ_RPAR_SET);
myKotlinParsing.parseAnnotationsList(EQ_RPAR_SET);
if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
IElementType declType = myKotlinParsing.parseProperty(KotlinParsing.DeclarationParsingMode.LOCAL);
@@ -1115,7 +1116,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
private boolean parseLocalDeclaration(boolean rollbackIfDefinitelyNotExpression, boolean isScriptTopLevel) {
PsiBuilder.Marker decl = mark();
KotlinParsing.ModifierDetector detector = new KotlinParsing.ModifierDetector();
myKotlinParsing.parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
myKotlinParsing.parseModifierList(detector, TokenSet.EMPTY);
IElementType declType = parseLocalDeclarationRest(detector, rollbackIfDefinitelyNotExpression, isScriptTopLevel);
@@ -1158,13 +1159,14 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
boolean paramsFound = false;
if (at(ARROW)) {
IElementType token = tt();
if (token == ARROW) {
// { -> ...}
mark().done(VALUE_PARAMETER_LIST);
advance(); // ARROW
paramsFound = true;
}
else if (at(IDENTIFIER) || at(COLON) || at(LPAR)) {
else if (token == IDENTIFIER || token == COLON || token == LPAR) {
// Try to parse a simple name list followed by an ARROW
// {a -> ...}
// {a, b -> ...}
@@ -1480,7 +1482,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
PsiBuilder.Marker parameter = mark();
if (!at(IN_KEYWORD)) {
myKotlinParsing.parseModifierList(DEFAULT, IN_KEYWORD_R_PAR_COLON_SET);
myKotlinParsing.parseModifierList(IN_KEYWORD_R_PAR_COLON_SET);
}
if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD
@@ -41,7 +41,7 @@ public class KotlinParser implements PsiParser {
// we need this method because we need psiFile
@NotNull
public ASTNode parse(IElementType iElementType, PsiBuilder psiBuilder, PsiFile psiFile) {
public static ASTNode parse(PsiBuilder psiBuilder, PsiFile psiFile) {
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
String extension = FileUtilRt.getExtension(psiFile.getName());
if (extension.isEmpty() || extension.equals(KotlinFileType.EXTENSION) || (psiFile instanceof KtFile && ((KtFile) psiFile).isCompiled())) {
@@ -74,6 +74,7 @@ class KotlinParserDefinition : ParserDefinition {
override fun createFile(fileViewProvider: FileViewProvider): PsiFile = KtFile(fileViewProvider, false)
@Deprecated("Deprecated in Java")
override fun spaceExistanceTypeBetweenTokens(left: ASTNode, right: ASTNode): ParserDefinition.SpaceRequirements {
val rightTokenType = right.elementType
@@ -287,7 +287,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
* ;
*/
PsiBuilder.Marker packageDirective = mark();
parseModifierList(DEFAULT, TokenSet.EMPTY);
parseModifierList(TokenSet.EMPTY);
if (at(PACKAGE_KEYWORD)) {
advance(); // PACKAGE_KEYWORD
@@ -495,7 +495,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
}
ModifierDetector detector = new ModifierDetector();
parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
parseModifierList(detector, TokenSet.EMPTY);
IElementType declType = parseCommonDeclaration(detector, NameParsingMode.REQUIRED, DeclarationParsingMode.MEMBER_OR_TOPLEVEL);
@@ -550,46 +550,36 @@ public class KotlinParsing extends AbstractKotlinParsing {
/*
* (modifier | annotation)*
*/
boolean parseModifierList(
@NotNull AnnotationParsingMode annotationParsingMode,
@NotNull TokenSet noModifiersBefore
) {
return parseModifierList(null, annotationParsingMode, noModifiersBefore);
boolean parseModifierList(@NotNull TokenSet noModifiersBefore) {
return parseModifierList(null, noModifiersBefore);
}
boolean parseAnnotationsList(
@NotNull AnnotationParsingMode annotationParsingMode,
@NotNull TokenSet noModifiersBefore
) {
return doParseModifierList(null, TokenSet.EMPTY, annotationParsingMode, noModifiersBefore);
void parseAnnotationsList(@NotNull TokenSet noModifiersBefore) {
doParseModifierList(null, TokenSet.EMPTY, AnnotationParsingMode.DEFAULT, noModifiersBefore);
}
/**
* (modifier | annotation)*
*
* <p>
* Feeds modifiers (not annotations) into the passed consumer, if it is not null
*
* @param noModifiersBefore is a token set with elements indicating when met them
* that previous token must be parsed as an identifier rather than modifier
*/
boolean parseModifierList(
@Nullable Consumer<IElementType> tokenConsumer,
@NotNull AnnotationParsingMode annotationParsingMode,
@NotNull TokenSet noModifiersBefore
) {
return doParseModifierList(tokenConsumer, MODIFIER_KEYWORDS, annotationParsingMode, noModifiersBefore);
boolean parseModifierList(@Nullable Consumer<IElementType> tokenConsumer, @NotNull TokenSet noModifiersBefore) {
return doParseModifierList(tokenConsumer, MODIFIER_KEYWORDS, AnnotationParsingMode.DEFAULT, noModifiersBefore);
}
private boolean parseFunctionTypeValueParameterModifierList() {
return doParseModifierList(null, RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS, NO_ANNOTATIONS, NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER);
private void parseFunctionTypeValueParameterModifierList() {
doParseModifierList(null, RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS, NO_ANNOTATIONS, NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER);
}
private boolean parseTypeModifierList() {
return doParseModifierList(null, TYPE_MODIFIER_KEYWORDS, TYPE_CONTEXT, TokenSet.EMPTY);
private void parseTypeModifierList() {
doParseModifierList(null, TYPE_MODIFIER_KEYWORDS, TYPE_CONTEXT, TokenSet.EMPTY);
}
private boolean parseTypeArgumentModifierList() {
return doParseModifierList(null, TYPE_ARGUMENT_MODIFIER_KEYWORDS, NO_ANNOTATIONS, COMMA_COLON_GT_SET);
private void parseTypeArgumentModifierList() {
doParseModifierList(null, TYPE_ARGUMENT_MODIFIER_KEYWORDS, NO_ANNOTATIONS, COMMA_COLON_GT_SET);
}
private boolean doParseModifierListBody(
@@ -951,7 +941,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
PsiBuilder.Marker reference = mark();
PsiBuilder.Marker typeReference = mark();
parseUserType(/* allowSimpleIntersectionTypes */ false);
parseUserType();
typeReference.done(TYPE_REFERENCE);
reference.done(CONSTRUCTOR_CALLEE);
@@ -1053,7 +1043,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
PsiBuilder.Marker beforeConstructorModifiers = mark();
PsiBuilder.Marker primaryConstructorMarker = mark();
boolean hasConstructorModifiers = parseModifierList(DEFAULT, TokenSet.EMPTY);
boolean hasConstructorModifiers = parseModifierList(TokenSet.EMPTY);
// Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
if (hasConstructorModifiers && !atSet(LPAR_LBRACE_COLON_CONSTRUCTOR_KEYWORD_SET)) {
@@ -1192,7 +1182,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
private ParseEnumEntryResult parseEnumEntry() {
PsiBuilder.Marker entry = mark();
parseModifierList(DEFAULT, COMMA_SEMICOLON_RBRACE_SET);
parseModifierList(COMMA_SEMICOLON_RBRACE_SET);
if (!atSet(SOFT_KEYWORDS_AT_MEMBER_START) && at(IDENTIFIER)) {
advance(); // IDENTIFIER
@@ -1301,7 +1291,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
}
ModifierDetector detector = new ModifierDetector();
parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
parseModifierList(detector, TokenSet.EMPTY);
IElementType declType = parseMemberDeclarationRest(detector);
@@ -1605,7 +1595,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
}
PsiBuilder.Marker property = mark();
parseModifierList(DEFAULT, COMMA_RPAR_COLON_EQ_SET);
parseModifierList(COMMA_RPAR_COLON_EQ_SET);
expect(IDENTIFIER, "Expecting a name", recoverySet);
@@ -1659,7 +1649,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
private PropertyComponentKind parsePropertyComponent(PropertyComponentKind.Collector notAllowedKind) {
PsiBuilder.Marker propertyComponent = mark();
parseModifierList(DEFAULT, TokenSet.EMPTY);
parseModifierList(TokenSet.EMPTY);
PropertyComponentKind propertyComponentKind;
if (at(GET_KEYWORD)) {
@@ -1701,7 +1691,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
if (propertyComponentKind == PropertyComponentKind.SET) {
PsiBuilder.Marker parameterList = mark();
PsiBuilder.Marker setterParameter = mark();
parseModifierList(DEFAULT, COMMA_COLON_RPAR_SET);
parseModifierList(COMMA_COLON_RPAR_SET);
expect(IDENTIFIER, "Expecting parameter name", RPAR_COLON_LBRACE_EQ_SET);
if (at(COLON)) {
@@ -1748,7 +1738,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
}
@NotNull
IElementType parseFunction() {
private IElementType parseFunction() {
return parseFunction(false);
}
@@ -1883,11 +1873,17 @@ public class KotlinParsing extends AbstractKotlinParsing {
/*
* IDENTIFIER
*/
private boolean parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, TokenSet recoverySet, boolean nameRequired) {
if (!nameRequired && atSet(nameFollow)) return true; // no name
private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, TokenSet recoverySet, boolean nameRequired) {
if (!nameRequired && atSet(nameFollow)) return; // no name
String expectingMessage = "Expecting " + title + " name" + (!receiverFound ? " or receiver type" : "");
return expect(IDENTIFIER, expectingMessage, recoverySet);
if (expect(IDENTIFIER)) {
return;
}
errorWithRecovery(
"Expecting " + title + " name" + (!receiverFound ? " or receiver type" : ""),
recoverySet
);
}
/*
@@ -2135,7 +2131,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
PsiBuilder.Marker mark = mark();
parseModifierList(DEFAULT, GT_COMMA_COLON_SET);
parseModifierList(GT_COMMA_COLON_SET);
expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
@@ -2209,7 +2205,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
dynamicType.done(DYNAMIC_TYPE);
}
else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
parseUserType(allowSimpleIntersectionTypes);
parseUserType();
}
else if (at(LPAR)) {
PsiBuilder.Marker functionOrParenthesizedType = mark();
@@ -2323,7 +2319,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
* - (Mutable)List<Foo>!
* - Array<(out) Foo>!
*/
private void parseUserType(boolean allowSimpleIntersectionTypes) {
private void parseUserType() {
PsiBuilder.Marker userType = mark();
if (at(PACKAGE_KEYWORD)) {
@@ -2416,15 +2412,14 @@ public class KotlinParsing extends AbstractKotlinParsing {
/*
* (optionalProjection type){","}
*/
private PsiBuilder.Marker parseTypeArgumentList() {
if (!at(LT)) return null;
private void parseTypeArgumentList() {
if (!at(LT)) return;
PsiBuilder.Marker list = mark();
tryParseTypeArgumentList(TokenSet.EMPTY);
list.done(TYPE_ARGUMENT_LIST);
return list;
}
boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) {
@@ -2566,7 +2561,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
private boolean parseValueParameter(boolean rollbackOnFailure, boolean typeRequired) {
PsiBuilder.Marker parameter = mark();
parseModifierList(DEFAULT, NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER);
parseModifierList(NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER);
if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
advance(); // VAR_KEYWORD | VAL_KEYWORD
@@ -2667,10 +2662,10 @@ public class KotlinParsing extends AbstractKotlinParsing {
WITH_SIGNIFICANT_WHITESPACE_BEFORE_ARGUMENTS(false, true, true, true),
NO_ANNOTATIONS(false, false, false, false);
boolean isFileAnnotationParsingMode;
boolean allowAnnotations;
boolean withSignificantWhitespaceBeforeArguments;
boolean typeContext;
final boolean isFileAnnotationParsingMode;
final boolean allowAnnotations;
final boolean withSignificantWhitespaceBeforeArguments;
final boolean typeContext;
AnnotationParsingMode(
boolean isFileAnnotationParsingMode,
@@ -20,10 +20,9 @@ public class LastBefore extends AbstractTokenStreamPattern {
private final boolean dontStopRightAfterOccurrence;
private final TokenStreamPredicate lookFor;
private final TokenStreamPredicate stopAt;
private boolean previousLookForResult;
public LastBefore(TokenStreamPredicate lookFor, TokenStreamPredicate stopAt, boolean dontStopRightAfterOccurrence) {
private LastBefore(TokenStreamPredicate lookFor, TokenStreamPredicate stopAt, boolean dontStopRightAfterOccurrence) {
this.lookFor = lookFor;
this.stopAt = stopAt;
this.dontStopRightAfterOccurrence = dontStopRightAfterOccurrence;
@@ -10,7 +10,7 @@ import com.intellij.util.text.LiteralFormatUtil
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.utils.extractRadix
private val FP_LITERAL_PARTS = "(?:([_\\d]*)\\.?([_\\d]*)e?[+-]?([_\\d]*))[f]?".toRegex()
private val FP_LITERAL_PARTS = "([_\\d]*)\\.?([_\\d]*)e?[+-]?([_\\d]*)[f]?".toRegex()
fun hasIllegalUnderscore(text: String, elementType: IElementType): Boolean {
val parts: List<String?> = if (elementType === KtNodeTypes.INTEGER_CONSTANT) {
@@ -79,32 +79,32 @@ private fun parseLong(text: String): Long? {
}
private fun parseFloatingLiteral(text: String): Number? {
if (text.lowercase().endsWith('f')) {
if (text.endsWith('f') || text.endsWith('F')) {
return parseFloat(text)
}
return parseDouble(text)
}
private fun parseDouble(text: String): Double? {
try {
return java.lang.Double.parseDouble(text)
return try {
java.lang.Double.parseDouble(text)
} catch (e: NumberFormatException) {
return null
null
}
}
private fun parseFloat(text: String): Float? {
try {
return java.lang.Float.parseFloat(text)
return try {
java.lang.Float.parseFloat(text)
} catch (e: NumberFormatException) {
return null
null
}
}
fun parseBoolean(text: String): Boolean {
if ("true".equals(text)) {
if ("true" == text) {
return true
} else if ("false".equals(text)) {
} else if ("false" == text) {
return false
}
@@ -32,5 +32,6 @@ public interface SemanticWhitespaceAwarePsiBuilder extends PsiBuilder {
void enableJoiningComplexTokens();
void disableJoiningComplexTokens();
@Override
boolean isWhitespaceOrComment(@NotNull IElementType elementType);
}
@@ -39,7 +39,7 @@ public class KtFileElementType extends IStubFileElementType<KotlinFileStub> {
public static KtFileElementType INSTANCE = new KtFileElementType();
public KtFileElementType() {
private KtFileElementType() {
super(NAME, KotlinLanguage.INSTANCE);
}
@@ -80,8 +80,7 @@ public class KtFileElementType extends IStubFileElementType<KotlinFileStub> {
Project project = psi.getProject();
Language languageForParser = getLanguageForParser(psi);
PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, null, languageForParser, chameleon.getChars());
KotlinParser parser = (KotlinParser) LanguageParserDefinitions.INSTANCE.forLanguage(languageForParser).createParser(project);
return parser.parse(this, builder, psi.getContainingFile()).getFirstChildNode();
return KotlinParser.parse(builder, psi.getContainingFile()).getFirstChildNode();
}
@Override