Parser: Disable joining complex tokens while parsing type references

#KT-8141 Fixed
This commit is contained in:
Alexey Sedunov
2015-06-19 14:43:29 +03:00
parent 0e9bcee0bc
commit 3266d8c29a
5 changed files with 375 additions and 35 deletions
@@ -1835,10 +1835,6 @@ public class JetParsing extends AbstractJetParsing {
// The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop
// on expression-indicating symbols or not
private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) {
// Disabling token merge is required for cases like
// Int?.(Foo) -> Bar
// we don't support this case now
// myBuilder.disableJoiningComplexTokens();
PsiBuilder.Marker typeRefMarker = mark();
parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS);
@@ -1898,7 +1894,11 @@ public class JetParsing extends AbstractJetParsing {
typeBeforeDot = false;
}
// Disabling token merge is required for cases like
// Int?.(Foo) -> Bar
myBuilder.disableJoiningComplexTokens();
typeRefMarker = parseNullableTypeSuffix(typeRefMarker);
myBuilder.restoreJoiningComplexTokensState();
if (typeBeforeDot && at(DOT)) {
// This is a receiver for a function type
@@ -1922,13 +1922,14 @@ public class JetParsing extends AbstractJetParsing {
functionType.done(FUNCTION_TYPE);
}
// myBuilder.restoreJoiningComplexTokensState();
return typeRefMarker;
}
@NotNull
PsiBuilder.Marker parseNullableTypeSuffix(@NotNull PsiBuilder.Marker typeRefMarker) {
while (at(QUEST)) {
// ?: is joined regardless of joining state
while (at(QUEST) && myBuilder.rawLookup(1) != COLON) {
PsiBuilder.Marker precede = typeRefMarker.precede();
advance(); // QUEST
typeRefMarker.done(NULLABLE_TYPE);
+53 -29
View File
@@ -503,18 +503,30 @@ JetFile: functionTypes.kt
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiErrorElement:Property getter or setter expected
PsiElement(SAFE_ACCESS)('?.')
PsiElement(LPAR)('(')
PsiElement(IDENTIFIER)('Int')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('Int')
FUNCTION_TYPE
FUNCTION_TYPE_RECEIVER
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(QUEST)('?')
PsiElement(DOT)('.')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiWhiteSpace('\n ')
PROPERTY
MODIFIER_LIST
@@ -1050,22 +1062,34 @@ JetFile: functionTypes.kt
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiErrorElement:Property getter or setter expected
PsiElement(SAFE_ACCESS)('?.')
PsiElement(LPAR)('(')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('Int')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('Int')
FUNCTION_TYPE
FUNCTION_TYPE_RECEIVER
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(QUEST)('?')
PsiElement(DOT)('.')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiWhiteSpace('\n ')
PROPERTY
MODIFIER_LIST
@@ -1273,4 +1297,4 @@ JetFile: functionTypes.kt
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiElement(RBRACE)('}')
@@ -0,0 +1,17 @@
fun test() {
x as? X ?: return
x as? X? : return
x as X? ?: return
X?::x
X ?:: x
X? ?:: x
X ??:: x
X ?? :: x
val x: X?.() -> Unit
val x: X??.() -> Unit
val x: X?? .() -> Unit
val x: X ? .() -> Unit
val x: X ?.() -> Unit
}
@@ -0,0 +1,292 @@
JetFile: nullableTypes.kt
PACKAGE_DIRECTIVE
<empty list>
IMPORT_LIST
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('test')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
BINARY_EXPRESSION
BINARY_WITH_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(AS_SAFE)('as?')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(ELVIS)('?:')
PsiWhiteSpace(' ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace('\n ')
BINARY_WITH_TYPE
BINARY_WITH_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(AS_SAFE)('as?')
PsiWhiteSpace(' ')
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiElement(QUEST)('?')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiErrorElement:Type expected
PsiElement(return)('return')
PsiWhiteSpace('\n ')
BINARY_EXPRESSION
BINARY_WITH_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(as)('as')
PsiWhiteSpace(' ')
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiElement(QUEST)('?')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(ELVIS)('?:')
PsiWhiteSpace(' ')
RETURN
PsiElement(return)('return')
PsiWhiteSpace('\n\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiElement(QUEST)('?')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiWhiteSpace(' ')
PsiElement(QUEST)('?')
PsiElement(COLONCOLON)('::')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
NULLABLE_TYPE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiElement(QUEST)('?')
PsiWhiteSpace(' ')
PsiElement(QUEST)('?')
PsiElement(COLONCOLON)('::')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
NULLABLE_TYPE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiWhiteSpace(' ')
PsiElement(QUEST)('?')
PsiElement(QUEST)('?')
PsiElement(COLONCOLON)('::')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
NULLABLE_TYPE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiWhiteSpace(' ')
PsiElement(QUEST)('?')
PsiElement(QUEST)('?')
PsiWhiteSpace(' ')
PsiElement(COLONCOLON)('::')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace('\n\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
FUNCTION_TYPE
FUNCTION_TYPE_RECEIVER
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiElement(QUEST)('?')
PsiElement(DOT)('.')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Unit')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
FUNCTION_TYPE
FUNCTION_TYPE_RECEIVER
TYPE_REFERENCE
NULLABLE_TYPE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiElement(QUEST)('?')
PsiElement(QUEST)('?')
PsiElement(DOT)('.')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Unit')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
FUNCTION_TYPE
FUNCTION_TYPE_RECEIVER
TYPE_REFERENCE
NULLABLE_TYPE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiElement(QUEST)('?')
PsiElement(QUEST)('?')
PsiWhiteSpace(' ')
PsiElement(DOT)('.')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Unit')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
FUNCTION_TYPE
FUNCTION_TYPE_RECEIVER
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiWhiteSpace(' ')
PsiElement(QUEST)('?')
PsiWhiteSpace(' ')
PsiElement(DOT)('.')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Unit')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
FUNCTION_TYPE
FUNCTION_TYPE_RECEIVER
TYPE_REFERENCE
NULLABLE_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('X')
PsiWhiteSpace(' ')
PsiElement(QUEST)('?')
PsiElement(DOT)('.')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Unit')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -1244,6 +1244,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/greatSyntacticShift/FunctionTypesAsArguments.kt");
doParsingTest(fileName);
}
@TestMetadata("nullableTypes.kt")
public void testNullableTypes() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/greatSyntacticShift/nullableTypes.kt");
doParsingTest(fileName);
}
}
@TestMetadata("compiler/testData/psi/kdoc")