KT-15677 KT-15775
Update parser & descriptor renderer to handle parenthesized types and function types properly. Resolve annotations in parenthesized types. AnnotationsImpl.isEmpty() returned false for targeted annotations only (e.g., 'fun @receiver:Ann C?.foo()'). Properly keep track of targeted annotations.
This commit is contained in:
@@ -163,6 +163,8 @@ public interface Errors {
|
||||
DiagnosticFactory1<KtElement, KotlinType> EXPANDED_TYPE_CANNOT_BE_CONSTRUCTED = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<KtTypeElement, KotlinType> EXPANDED_TYPE_CANNOT_BE_INHERITED = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtModifierList> MODIFIER_LIST_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Errors in declarations
|
||||
|
||||
+2
@@ -521,6 +521,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(EXPANDED_TYPE_CANNOT_BE_CONSTRUCTED, "Expanded type {0} contains non-invariant projections in top-level arguments and cannot be constructed", RENDER_TYPE);
|
||||
MAP.put(EXPANDED_TYPE_CANNOT_BE_INHERITED, "Expanded type {0} contains non-invariant projections in top-level arguments and cannot be inherited from", RENDER_TYPE);
|
||||
|
||||
MAP.put(MODIFIER_LIST_NOT_ALLOWED, "Modifiers and annotations are not allowed here, because there are other modifiers or annotations outside of parenthesis");
|
||||
|
||||
MAP.put(TOO_MANY_ARGUMENTS, "Too many arguments for {0}", FQ_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(CONSTANT_EXPECTED_TYPE_MISMATCH, "The {0} literal does not conform to the expected type {1}", STRING, RENDER_TYPE);
|
||||
|
||||
@@ -232,7 +232,7 @@ public interface KtTokens {
|
||||
|
||||
TokenSet TYPE_MODIFIER_KEYWORDS = TokenSet.create(SUSPEND_KEYWORD);
|
||||
TokenSet TYPE_ARGUMENT_MODIFIER_KEYWORDS = TokenSet.create(IN_KEYWORD, OUT_KEYWORD);
|
||||
TokenSet RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS = TokenSet.create(OUT_KEYWORD, VARARG_KEYWORD); // lazy, out, ref
|
||||
TokenSet RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS = TokenSet.create(OUT_KEYWORD, VARARG_KEYWORD);
|
||||
|
||||
TokenSet VISIBILITY_MODIFIERS = TokenSet.create(PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD);
|
||||
|
||||
|
||||
@@ -461,8 +461,8 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
return doParseModifierList(tokenConsumer, MODIFIER_KEYWORDS, annotationParsingMode, noModifiersBefore);
|
||||
}
|
||||
|
||||
private boolean parseValueParameterModifierList() {
|
||||
return doParseModifierList(null, RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS, DEFAULT, NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER);
|
||||
private boolean parseFunctionTypeValueParameterModifierList() {
|
||||
return doParseModifierList(null, RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS, NO_ANNOTATIONS, NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER);
|
||||
}
|
||||
|
||||
private boolean parseTypeModifierList() {
|
||||
@@ -2196,7 +2196,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
if (isFunctionTypeContents) {
|
||||
if (!tryParseValueParameter(typeRequired)) {
|
||||
PsiBuilder.Marker valueParameter = mark();
|
||||
parseValueParameterModifierList(); // lazy, out, ref
|
||||
parseFunctionTypeValueParameterModifierList();
|
||||
parseTypeRef();
|
||||
closeDeclarationWithCommentBinders(valueParameter, VALUE_PARAMETER, false);
|
||||
}
|
||||
|
||||
@@ -57,4 +57,16 @@ public class KtNullableType extends KtElementImplStub<KotlinPlaceHolderStub<KtNu
|
||||
public KtTypeElement getInnerType() {
|
||||
return KtStubbedPsiUtil.getStubOrPsiChild(this, KtStubElementTypes.TYPE_ELEMENT_TYPES, KtTypeElement.ARRAY_FACTORY);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public KtModifierList getModifierList() {
|
||||
return getStubOrPsiChild(KtStubElementTypes.MODIFIER_LIST);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<KtAnnotationEntry> getAnnotationEntries() {
|
||||
KtModifierList modifierList = getModifierList();
|
||||
return modifierList != null ? modifierList.getAnnotationEntries()
|
||||
: Collections.<KtAnnotationEntry>emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.context.TypeLazinessToken
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.debugTypeInfo
|
||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
|
||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
import org.jetbrains.kotlin.resolve.PossiblyBareType.bare
|
||||
import org.jetbrains.kotlin.resolve.PossiblyBareType.type
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScope
|
||||
@@ -131,10 +133,10 @@ class TypeResolver(
|
||||
}
|
||||
|
||||
private fun doResolvePossiblyBareType(c: TypeResolutionContext, typeReference: KtTypeReference): PossiblyBareType {
|
||||
val annotations = annotationResolver.resolveAnnotationsWithoutArguments(c.scope, typeReference.getAnnotationEntries(), c.trace)
|
||||
|
||||
val typeElement = typeReference.typeElement
|
||||
|
||||
val annotations = resolveTypeAnnotations(c, typeReference)
|
||||
|
||||
val type = resolveTypeElement(c, annotations, typeReference.modifierList, typeElement)
|
||||
c.trace.recordScope(c.scope, typeReference)
|
||||
|
||||
@@ -147,6 +149,29 @@ class TypeResolver(
|
||||
return type
|
||||
}
|
||||
|
||||
internal fun KtElementImplStub<*>.getAllModifierLists(): Array<out KtDeclarationModifierList> =
|
||||
getStubOrPsiChildren(KtStubElementTypes.MODIFIER_LIST, KtStubElementTypes.MODIFIER_LIST.arrayFactory)
|
||||
|
||||
private fun resolveTypeAnnotations(c: TypeResolutionContext, modifierListsOwner: KtElementImplStub<*>): Annotations {
|
||||
val modifierLists = modifierListsOwner.getAllModifierLists()
|
||||
|
||||
var result = Annotations.EMPTY
|
||||
var isSplitModifierList = false
|
||||
|
||||
for (modifierList in modifierLists) {
|
||||
if (isSplitModifierList) {
|
||||
c.trace.report(MODIFIER_LIST_NOT_ALLOWED.on(modifierList))
|
||||
}
|
||||
|
||||
val annotations = annotationResolver.resolveAnnotationsWithoutArguments(c.scope, modifierList.annotationEntries, c.trace)
|
||||
result = composeAnnotations(result, annotations)
|
||||
|
||||
isSplitModifierList = true
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is light version of ForceResolveUtil.forceResolveAllContents
|
||||
* We can't use ForceResolveUtil.forceResolveAllContents here because it runs ForceResolveUtil.forceResolveAllContents(getConstructor()),
|
||||
@@ -176,12 +201,12 @@ class TypeResolver(
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveTypeElement(c: TypeResolutionContext, annotations: Annotations, modifiers: KtModifierList?, typeElement: KtTypeElement?): PossiblyBareType {
|
||||
private fun resolveTypeElement(c: TypeResolutionContext, annotations: Annotations, outerModifierList: KtModifierList?, typeElement: KtTypeElement?): PossiblyBareType {
|
||||
var result: PossiblyBareType? = null
|
||||
|
||||
val hasSuspendModifier = modifiers?.hasModifier(KtTokens.SUSPEND_KEYWORD) ?: false
|
||||
val suspendModifier = modifiers?.getModifier(KtTokens.SUSPEND_KEYWORD)
|
||||
if (hasSuspendModifier && typeElement !is KtFunctionType) {
|
||||
val hasSuspendModifier = outerModifierList?.hasModifier(KtTokens.SUSPEND_KEYWORD) ?: false
|
||||
val suspendModifier = outerModifierList?.getModifier(KtTokens.SUSPEND_KEYWORD)
|
||||
if (hasSuspendModifier && !typeElement.canHaveFunctionTypeModifiers()) {
|
||||
c.trace.report(Errors.WRONG_MODIFIER_TARGET.on(suspendModifier!!, KtTokens.SUSPEND_KEYWORD, "non-functional type"))
|
||||
}
|
||||
else if (hasSuspendModifier) {
|
||||
@@ -208,8 +233,15 @@ class TypeResolver(
|
||||
}
|
||||
|
||||
override fun visitNullableType(nullableType: KtNullableType) {
|
||||
val innerType = nullableType.getInnerType()
|
||||
val baseType = resolveTypeElement(c, annotations, modifiers, innerType)
|
||||
val innerModifierList = nullableType.modifierList
|
||||
if (innerModifierList != null && outerModifierList != null) {
|
||||
c.trace.report(MODIFIER_LIST_NOT_ALLOWED.on(innerModifierList))
|
||||
}
|
||||
|
||||
val innerAnnotations = composeAnnotations(annotations, resolveTypeAnnotations(c, nullableType))
|
||||
|
||||
val innerType = nullableType.innerType
|
||||
val baseType = resolveTypeElement(c, innerAnnotations, outerModifierList ?: innerModifierList, innerType)
|
||||
if (baseType.isNullable || innerType is KtNullableType || innerType is KtDynamicType) {
|
||||
c.trace.report(REDUNDANT_NULLABLE.on(nullableType))
|
||||
}
|
||||
@@ -319,6 +351,9 @@ class TypeResolver(
|
||||
return result ?: type(ErrorUtils.createErrorType(typeElement?.getDebugText() ?: "No type element"))
|
||||
}
|
||||
|
||||
private fun KtTypeElement?.canHaveFunctionTypeModifiers(): Boolean =
|
||||
this is KtFunctionType
|
||||
|
||||
private fun resolveTypeForTypeParameter(
|
||||
c: TypeResolutionContext, annotations: Annotations,
|
||||
typeParameter: TypeParameterDescriptor,
|
||||
|
||||
Reference in New Issue
Block a user