Support nullable types on left-hand side of ::
#KT-1183 In Progress
This commit is contained in:
@@ -372,7 +372,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* callableReference
|
||||
* : userType? "::" SimpleName
|
||||
* : (userType "?"*)? "::" SimpleName
|
||||
* ;
|
||||
*/
|
||||
private boolean parseCallableReferenceExpression() {
|
||||
@@ -381,7 +381,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
if (!at(COLONCOLON)) {
|
||||
PsiBuilder.Marker typeReference = mark();
|
||||
myJetParsing.parseUserType();
|
||||
typeReference = myJetParsing.parseNullableTypeSuffix(typeReference);
|
||||
typeReference.done(TYPE_REFERENCE);
|
||||
|
||||
if (!at(COLONCOLON)) {
|
||||
expression.rollbackTo();
|
||||
return false;
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.parsing;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeType;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
@@ -1478,14 +1479,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet));
|
||||
}
|
||||
|
||||
while (at(QUEST)) {
|
||||
PsiBuilder.Marker precede = typeRefMarker.precede();
|
||||
|
||||
advance(); // QUEST
|
||||
typeRefMarker.done(NULLABLE_TYPE);
|
||||
|
||||
typeRefMarker = precede;
|
||||
}
|
||||
typeRefMarker = parseNullableTypeSuffix(typeRefMarker);
|
||||
|
||||
if (at(DOT)) {
|
||||
// This is a receiver for a function type
|
||||
@@ -1513,6 +1507,17 @@ public class JetParsing extends AbstractJetParsing {
|
||||
return typeRefMarker;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
PsiBuilder.Marker parseNullableTypeSuffix(@NotNull PsiBuilder.Marker typeRefMarker) {
|
||||
while (at(QUEST)) {
|
||||
PsiBuilder.Marker precede = typeRefMarker.precede();
|
||||
advance(); // QUEST
|
||||
typeRefMarker.done(NULLABLE_TYPE);
|
||||
typeRefMarker = precede;
|
||||
}
|
||||
return typeRefMarker;
|
||||
}
|
||||
|
||||
/*
|
||||
* userType
|
||||
* : ("package" ".")? simpleUserType{"."}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
fun A?.foo() {}
|
||||
|
||||
val f = A::foo : KMemberFunction0<A, Unit>
|
||||
val g = A?::foo : KExtensionFunction0<A, Unit>
|
||||
@@ -23,6 +23,11 @@ fun ok() {
|
||||
(a::b)()
|
||||
a.(b::c)()
|
||||
a.b::c()
|
||||
|
||||
a?::b
|
||||
a??::b
|
||||
a<b>?::c
|
||||
a<b?,c?>?::d
|
||||
}
|
||||
|
||||
fun err0() {
|
||||
|
||||
@@ -392,6 +392,78 @@ JetFile: DoubleColon.kt
|
||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
CALLABLE_REFERENCE_EXPRESSION
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiElement(COLONCOLON)('::')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiWhiteSpace('\n ')
|
||||
CALLABLE_REFERENCE_EXPRESSION
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiElement(COLONCOLON)('::')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiWhiteSpace('\n ')
|
||||
CALLABLE_REFERENCE_EXPRESSION
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
TYPE_ARGUMENT_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PROJECTION
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(GT)('>')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiElement(COLONCOLON)('::')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('c')
|
||||
PsiWhiteSpace('\n ')
|
||||
CALLABLE_REFERENCE_EXPRESSION
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
TYPE_ARGUMENT_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PROJECTION
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiElement(COMMA)(',')
|
||||
TYPE_PROJECTION
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('c')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiElement(GT)('>')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiElement(COLONCOLON)('::')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('d')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
|
||||
@@ -192,6 +192,11 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/extensionInClassDisallowed.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionOnNullable.kt")
|
||||
public void testExtensionOnNullable() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/extensionOnNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericClassFromTopLevel.kt")
|
||||
public void testGenericClassFromTopLevel() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/genericClassFromTopLevel.kt");
|
||||
|
||||
@@ -104,7 +104,7 @@ postfixUnaryExpression
|
||||
|
||||
// TODO: callSuffix is forbidden after callableReference, since parentheses will be used to provide parameter types
|
||||
callableReference
|
||||
: userType? "::" SimpleName
|
||||
: (userType "?"*)? "::" SimpleName
|
||||
;
|
||||
|
||||
// !!! When you add here, remember to update the FIRST set in the parser
|
||||
|
||||
Reference in New Issue
Block a user