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
|
* callableReference
|
||||||
* : userType? "::" SimpleName
|
* : (userType "?"*)? "::" SimpleName
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private boolean parseCallableReferenceExpression() {
|
private boolean parseCallableReferenceExpression() {
|
||||||
@@ -381,7 +381,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
if (!at(COLONCOLON)) {
|
if (!at(COLONCOLON)) {
|
||||||
PsiBuilder.Marker typeReference = mark();
|
PsiBuilder.Marker typeReference = mark();
|
||||||
myJetParsing.parseUserType();
|
myJetParsing.parseUserType();
|
||||||
|
typeReference = myJetParsing.parseNullableTypeSuffix(typeReference);
|
||||||
typeReference.done(TYPE_REFERENCE);
|
typeReference.done(TYPE_REFERENCE);
|
||||||
|
|
||||||
if (!at(COLONCOLON)) {
|
if (!at(COLONCOLON)) {
|
||||||
expression.rollbackTo();
|
expression.rollbackTo();
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.parsing;
|
|||||||
import com.intellij.lang.PsiBuilder;
|
import com.intellij.lang.PsiBuilder;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.psi.tree.TokenSet;
|
import com.intellij.psi.tree.TokenSet;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetNodeType;
|
import org.jetbrains.jet.JetNodeType;
|
||||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
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));
|
TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (at(QUEST)) {
|
typeRefMarker = parseNullableTypeSuffix(typeRefMarker);
|
||||||
PsiBuilder.Marker precede = typeRefMarker.precede();
|
|
||||||
|
|
||||||
advance(); // QUEST
|
|
||||||
typeRefMarker.done(NULLABLE_TYPE);
|
|
||||||
|
|
||||||
typeRefMarker = precede;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (at(DOT)) {
|
if (at(DOT)) {
|
||||||
// This is a receiver for a function type
|
// This is a receiver for a function type
|
||||||
@@ -1513,6 +1507,17 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
return typeRefMarker;
|
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
|
* userType
|
||||||
* : ("package" ".")? simpleUserType{"."}
|
* : ("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)()
|
||||||
a.(b::c)()
|
a.(b::c)()
|
||||||
a.b::c()
|
a.b::c()
|
||||||
|
|
||||||
|
a?::b
|
||||||
|
a??::b
|
||||||
|
a<b>?::c
|
||||||
|
a<b?,c?>?::d
|
||||||
}
|
}
|
||||||
|
|
||||||
fun err0() {
|
fun err0() {
|
||||||
|
|||||||
@@ -392,6 +392,78 @@ JetFile: DoubleColon.kt
|
|||||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||||
PsiElement(LPAR)('(')
|
PsiElement(LPAR)('(')
|
||||||
PsiElement(RPAR)(')')
|
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')
|
PsiWhiteSpace('\n')
|
||||||
PsiElement(RBRACE)('}')
|
PsiElement(RBRACE)('}')
|
||||||
PsiWhiteSpace('\n\n')
|
PsiWhiteSpace('\n\n')
|
||||||
|
|||||||
@@ -192,6 +192,11 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
|
|||||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/extensionInClassDisallowed.kt");
|
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")
|
@TestMetadata("genericClassFromTopLevel.kt")
|
||||||
public void testGenericClassFromTopLevel() throws Exception {
|
public void testGenericClassFromTopLevel() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/genericClassFromTopLevel.kt");
|
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
|
// TODO: callSuffix is forbidden after callableReference, since parentheses will be used to provide parameter types
|
||||||
callableReference
|
callableReference
|
||||||
: userType? "::" SimpleName
|
: (userType "?"*)? "::" SimpleName
|
||||||
;
|
;
|
||||||
|
|
||||||
// !!! When you add here, remember to update the FIRST set in the parser
|
// !!! When you add here, remember to update the FIRST set in the parser
|
||||||
|
|||||||
Reference in New Issue
Block a user