Support new form of definitely non-nullable types: T & Any
^KT-26245 In Progress
This commit is contained in:
committed by
teamcityserver
parent
cdd8d1c163
commit
302eacbf59
@@ -76,6 +76,7 @@ public interface KtNodeTypes {
|
||||
IElementType FUNCTION_TYPE_RECEIVER = KtStubElementTypes.FUNCTION_TYPE_RECEIVER;
|
||||
IElementType NULLABLE_TYPE = KtStubElementTypes.NULLABLE_TYPE;
|
||||
IElementType DEFINITELY_NOT_NULL_TYPE = KtStubElementTypes.DEFINITELY_NOT_NULL_TYPE;
|
||||
IElementType INTERSECTION_TYPE = KtStubElementTypes.INTERSECTION_TYPE;
|
||||
IElementType TYPE_PROJECTION = KtStubElementTypes.TYPE_PROJECTION;
|
||||
|
||||
IElementType PROPERTY_ACCESSOR = KtStubElementTypes.PROPERTY_ACCESSOR;
|
||||
|
||||
@@ -158,7 +158,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
||||
AS(AS_KEYWORD, AS_SAFE) {
|
||||
@Override
|
||||
public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser) {
|
||||
parser.myKotlinParsing.parseTypeRefWithoutDefinitelyNotNull();
|
||||
parser.myKotlinParsing.parseTypeRefWithoutIntersections();
|
||||
return BINARY_WITH_TYPE;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
||||
@Override
|
||||
public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser) {
|
||||
if (operation == IS_KEYWORD || operation == NOT_IS) {
|
||||
parser.myKotlinParsing.parseTypeRefWithoutDefinitelyNotNull();
|
||||
parser.myKotlinParsing.parseTypeRefWithoutIntersections();
|
||||
return IS_EXPRESSION;
|
||||
}
|
||||
|
||||
|
||||
@@ -833,7 +833,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
|
||||
PsiBuilder.Marker reference = mark();
|
||||
PsiBuilder.Marker typeReference = mark();
|
||||
parseUserType(/* allowNotNullTypeParameter */ false);
|
||||
parseUserType(/* allowSimpleIntersectionTypes */ false);
|
||||
typeReference.done(TYPE_REFERENCE);
|
||||
reference.done(CONSTRUCTOR_CALLEE);
|
||||
|
||||
@@ -1713,7 +1713,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
|
||||
if (!receiverPresent) return false;
|
||||
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
createTruncatedBuilder(lastDot).parseTypeRefWithoutIntersections();
|
||||
|
||||
if (atSet(RECEIVER_TYPE_TERMINATORS)) {
|
||||
advance(); // expectation
|
||||
@@ -2055,22 +2055,22 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
parseTypeRef(TokenSet.EMPTY);
|
||||
}
|
||||
|
||||
void parseTypeRefWithoutDefinitelyNotNull() {
|
||||
parseTypeRef(TokenSet.EMPTY, /* allowNotNullTypeParameters */ false);
|
||||
void parseTypeRefWithoutIntersections() {
|
||||
parseTypeRef(TokenSet.EMPTY, /* allowSimpleIntersectionTypes */ false);
|
||||
}
|
||||
|
||||
void parseTypeRef(TokenSet extraRecoverySet) {
|
||||
parseTypeRef(extraRecoverySet, /* allowNotNullTypeParameters */ true);
|
||||
parseTypeRef(extraRecoverySet, /* allowSimpleIntersectionTypes */ true);
|
||||
}
|
||||
|
||||
private void parseTypeRef(TokenSet extraRecoverySet, boolean allowNotNullTypeParameters) {
|
||||
PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet, allowNotNullTypeParameters);
|
||||
private void parseTypeRef(TokenSet extraRecoverySet, boolean allowSimpleIntersectionTypes) {
|
||||
PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet, allowSimpleIntersectionTypes);
|
||||
typeRefMarker.done(TYPE_REFERENCE);
|
||||
}
|
||||
|
||||
// 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, boolean allowNotNullTypeParameters) {
|
||||
private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet, boolean allowSimpleIntersectionTypes) {
|
||||
PsiBuilder.Marker typeRefMarker = mark();
|
||||
|
||||
parseTypeModifierList();
|
||||
@@ -2086,14 +2086,14 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
dynamicType.done(DYNAMIC_TYPE);
|
||||
}
|
||||
else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
|
||||
parseUserType(allowNotNullTypeParameters);
|
||||
parseUserType(allowSimpleIntersectionTypes);
|
||||
}
|
||||
else if (at(LPAR)) {
|
||||
PsiBuilder.Marker functionOrParenthesizedType = mark();
|
||||
|
||||
// This may be a function parameter list or just a parenthesized type
|
||||
advance(); // LPAR
|
||||
parseTypeRefContents(TokenSet.EMPTY, allowNotNullTypeParameters).drop(); // parenthesized types, no reference element around it is needed
|
||||
parseTypeRefContents(TokenSet.EMPTY, /* allowSimpleIntersectionTypes */ true).drop(); // parenthesized types, no reference element around it is needed
|
||||
|
||||
if (at(RPAR)) {
|
||||
advance(); // RPAR
|
||||
@@ -2133,7 +2133,23 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
typeElementMarker = parseNullableTypeSuffix(typeElementMarker);
|
||||
myBuilder.restoreJoiningComplexTokensState();
|
||||
|
||||
if (typeBeforeDot && at(DOT)) {
|
||||
boolean wasIntersection = false;
|
||||
if (allowSimpleIntersectionTypes && at(AND)) {
|
||||
PsiBuilder.Marker leftTypeRef = typeElementMarker;
|
||||
|
||||
typeElementMarker = typeElementMarker.precede();
|
||||
PsiBuilder.Marker intersectionType = leftTypeRef.precede();
|
||||
|
||||
leftTypeRef.done(TYPE_REFERENCE);
|
||||
|
||||
advance(); // &
|
||||
parseTypeRef(extraRecoverySet, /* allowSimpleIntersectionTypes */ true);
|
||||
|
||||
intersectionType.done(INTERSECTION_TYPE);
|
||||
wasIntersection = true;
|
||||
}
|
||||
|
||||
if (typeBeforeDot && !wasIntersection && at(DOT)) {
|
||||
// This is a receiver for a function type
|
||||
// A.(B) -> C
|
||||
// ^
|
||||
@@ -2183,7 +2199,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
* - (Mutable)List<Foo>!
|
||||
* - Array<(out) Foo>!
|
||||
*/
|
||||
private void parseUserType(boolean allowNotNullTypeParameter) {
|
||||
private void parseUserType(boolean allowSimpleIntersectionTypes) {
|
||||
PsiBuilder.Marker userType = mark();
|
||||
|
||||
if (at(PACKAGE_KEYWORD)) {
|
||||
@@ -2228,12 +2244,6 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
|
||||
userType.done(USER_TYPE);
|
||||
|
||||
if (allowNotNullTypeParameter && at(EXCLEXCL)) {
|
||||
PsiBuilder.Marker definitelyNotNull = userType.precede();
|
||||
advance(); // !!
|
||||
definitelyNotNull.done(DEFINITELY_NOT_NULL_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean atParenthesizedMutableForPlatformTypes(int offset) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi
|
||||
|
||||
import com.intellij.lang.ASTNode
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
|
||||
class KtIntersectionType : KtElementImplStub<KotlinPlaceHolderStub<KtIntersectionType>>, KtTypeElement {
|
||||
constructor(node: ASTNode) : super(node)
|
||||
constructor(stub: KotlinPlaceHolderStub<KtIntersectionType>) : super(stub, KtStubElementTypes.INTERSECTION_TYPE)
|
||||
|
||||
override fun getTypeArgumentsAsTypes(): List<KtTypeReference> = emptyList()
|
||||
|
||||
fun getLeftTypeRef(): KtTypeReference? = getStubOrPsiChildrenAsList(KtStubElementTypes.TYPE_REFERENCE).getOrNull(0)
|
||||
fun getRightTypeRef(): KtTypeReference? = getStubOrPsiChildrenAsList(KtStubElementTypes.TYPE_REFERENCE).getOrNull(1)
|
||||
|
||||
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D): R {
|
||||
return visitor.visitIntersectionType(this, data)
|
||||
}
|
||||
}
|
||||
@@ -406,6 +406,10 @@ public class KtVisitor<R, D> extends PsiElementVisitor {
|
||||
return visitTypeElement(definitelyNotNullType, data);
|
||||
}
|
||||
|
||||
public R visitIntersectionType(@NotNull KtIntersectionType definitelyNotNullType, D data) {
|
||||
return visitTypeElement(definitelyNotNullType, data);
|
||||
}
|
||||
|
||||
public R visitTypeProjection(@NotNull KtTypeProjection typeProjection, D data) {
|
||||
return visitKtElement(typeProjection, data);
|
||||
}
|
||||
|
||||
@@ -389,6 +389,10 @@ public class KtVisitorVoid extends KtVisitor<Void, Void> {
|
||||
super.visitDefinitelyNotNullType(definitelyNotNullType, null);
|
||||
}
|
||||
|
||||
public void visitIntersectionType(@NotNull KtIntersectionType intersectionType) {
|
||||
super.visitIntersectionType(intersectionType, null);
|
||||
}
|
||||
|
||||
public void visitTypeProjection(@NotNull KtTypeProjection typeProjection) {
|
||||
super.visitTypeProjection(typeProjection, null);
|
||||
}
|
||||
@@ -982,6 +986,12 @@ public class KtVisitorVoid extends KtVisitor<Void, Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitIntersectionType(@NotNull KtIntersectionType intersectionType, Void data) {
|
||||
visitIntersectionType(intersectionType);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Void visitTypeProjection(@NotNull KtTypeProjection typeProjection, Void data) {
|
||||
visitTypeProjection(typeProjection);
|
||||
|
||||
@@ -82,6 +82,9 @@ public interface KtStubElementTypes {
|
||||
KtPlaceHolderStubElementType<KtDefinitelyNotNullType> DEFINITELY_NOT_NULL_TYPE =
|
||||
new KtPlaceHolderStubElementType<>("DEFINITELY_NOT_NULL_TYPE", KtDefinitelyNotNullType.class);
|
||||
|
||||
KtPlaceHolderStubElementType<KtIntersectionType> INTERSECTION_TYPE =
|
||||
new KtPlaceHolderStubElementType<>("INTERSECTION_TYPE", KtIntersectionType.class);
|
||||
|
||||
KtPlaceHolderStubElementType<KtTypeReference> TYPE_REFERENCE =
|
||||
new KtPlaceHolderStubElementType<>("TYPE_REFERENCE", KtTypeReference.class);
|
||||
|
||||
@@ -170,7 +173,7 @@ public interface KtStubElementTypes {
|
||||
|
||||
TokenSet SUPER_TYPE_LIST_ENTRIES = TokenSet.create(DELEGATED_SUPER_TYPE_ENTRY, SUPER_TYPE_CALL_ENTRY, SUPER_TYPE_ENTRY);
|
||||
|
||||
TokenSet TYPE_ELEMENT_TYPES = TokenSet.create(USER_TYPE, NULLABLE_TYPE, FUNCTION_TYPE, DYNAMIC_TYPE, DEFINITELY_NOT_NULL_TYPE);
|
||||
TokenSet TYPE_ELEMENT_TYPES = TokenSet.create(USER_TYPE, NULLABLE_TYPE, FUNCTION_TYPE, DYNAMIC_TYPE, INTERSECTION_TYPE);
|
||||
|
||||
TokenSet INSIDE_DIRECTIVE_EXPRESSIONS = TokenSet.create(REFERENCE_EXPRESSION, DOT_QUALIFIED_EXPRESSION);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user