[PSI, FE] Support functional types
This commit is contained in:
committed by
TeamCityServer
parent
e53cee77a3
commit
e3f987459c
@@ -2172,6 +2172,12 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
IElementType lookahead = lookahead(1);
|
||||
IElementType lookahead2 = lookahead(2);
|
||||
boolean typeBeforeDot = true;
|
||||
boolean withContextReceiver = at(CONTEXT_KEYWORD) && lookahead == LPAR;
|
||||
|
||||
if (withContextReceiver) {
|
||||
parseContextReceiverList();
|
||||
}
|
||||
|
||||
if (at(IDENTIFIER) && !(lookahead == DOT && lookahead2 == IDENTIFIER) && lookahead != LT && at(DYNAMIC_KEYWORD)) {
|
||||
PsiBuilder.Marker dynamicType = mark();
|
||||
advance(); // DYNAMIC_KEYWORD
|
||||
@@ -2180,7 +2186,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
|
||||
parseUserType(allowSimpleIntersectionTypes);
|
||||
}
|
||||
else if (at(LPAR)) {
|
||||
else if (at(LPAR) && !withContextReceiver) {
|
||||
PsiBuilder.Marker functionOrParenthesizedType = mark();
|
||||
|
||||
// This may be a function parameter list or just a parenthesized type
|
||||
@@ -2211,7 +2217,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
else if (!withContextReceiver) {
|
||||
errorWithRecovery("Type expected",
|
||||
TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST,
|
||||
TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON),
|
||||
@@ -2240,8 +2246,10 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
intersectionType.done(INTERSECTION_TYPE);
|
||||
wasIntersection = true;
|
||||
}
|
||||
boolean withExtensionReceiver = typeBeforeDot && at(DOT);
|
||||
|
||||
if (typeBeforeDot && !wasIntersection && at(DOT)) {
|
||||
|
||||
if (withExtensionReceiver && !wasIntersection || withContextReceiver) {
|
||||
// This is a receiver for a function type
|
||||
// A.(B) -> C
|
||||
// ^
|
||||
@@ -2253,7 +2261,9 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
receiverTypeRef.done(TYPE_REFERENCE);
|
||||
receiverType.done(FUNCTION_TYPE_RECEIVER);
|
||||
|
||||
advance(); // DOT
|
||||
if (withExtensionReceiver) {
|
||||
advance(); // DOT
|
||||
}
|
||||
|
||||
if (at(LPAR)) {
|
||||
parseFunctionTypeContents().drop();
|
||||
|
||||
@@ -45,6 +45,10 @@ public class KtFunctionType extends KtElementImplStub<KotlinPlaceHolderStub<KtFu
|
||||
@Override
|
||||
public List<KtTypeReference> getTypeArgumentsAsTypes() {
|
||||
ArrayList<KtTypeReference> result = Lists.newArrayList();
|
||||
List<KtTypeReference> contextReceiversTypeRefs = getContextReceiversTypeReferences();
|
||||
if (contextReceiversTypeRefs != null) {
|
||||
result.addAll(contextReceiversTypeRefs);
|
||||
}
|
||||
KtTypeReference receiverTypeRef = getReceiverTypeReference();
|
||||
if (receiverTypeRef != null) {
|
||||
result.add(receiverTypeRef);
|
||||
@@ -89,6 +93,20 @@ public class KtFunctionType extends KtElementImplStub<KotlinPlaceHolderStub<KtFu
|
||||
return receiverDeclaration.getTypeReference();
|
||||
}
|
||||
|
||||
public List<KtTypeReference> getContextReceiversTypeReferences() {
|
||||
KtFunctionTypeReceiver receiverDeclaration = getReceiver();
|
||||
if (receiverDeclaration == null) {
|
||||
return null;
|
||||
}
|
||||
KtTypeReference receiverTypeRef = receiverDeclaration.getTypeReference();
|
||||
KtContextReceiverList contextReceiverList = receiverTypeRef.getStubOrPsiChild(KtStubElementTypes.CONTEXT_RECEIVER_LIST);
|
||||
if (contextReceiverList != null) {
|
||||
return contextReceiverList.typeReferences();
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public KtTypeReference getReturnTypeReference() {
|
||||
return getStubOrPsiChild(KtStubElementTypes.TYPE_REFERENCE);
|
||||
|
||||
Reference in New Issue
Block a user