Update annotation rendering in diagnostics
Disable annotation rendering in default type and descriptor renderers. Preserve annotations in Android and Serialization plugins. Update error texts in ide tests. Nullability annotations in Java descriptors are rendered with context-dependent renderer. #KT-20258 Fixed
This commit is contained in:
@@ -11,12 +11,12 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo;
|
||||
import org.jetbrains.kotlin.cfg.WhenMissingCase;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.config.LanguageVersion;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DeclarationWithDiagnosticComponents;
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
@@ -475,7 +475,7 @@ public interface Errors {
|
||||
DiagnosticFactory3.create(ERROR, VISIBILITY_MODIFIER);
|
||||
DiagnosticFactory3<KtModifierListOwner, Visibility, CallableMemberDescriptor, DeclarationDescriptor> CANNOT_CHANGE_ACCESS_PRIVILEGE =
|
||||
DiagnosticFactory3.create(ERROR, VISIBILITY_MODIFIER);
|
||||
DiagnosticFactory2<KtNamedDeclaration, CallableMemberDescriptor, CallableMemberDescriptor> RETURN_TYPE_MISMATCH_ON_OVERRIDE =
|
||||
DiagnosticFactory2<KtNamedDeclaration, CallableMemberDescriptor, DeclarationWithDiagnosticComponents> RETURN_TYPE_MISMATCH_ON_OVERRIDE =
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_RETURN_TYPE);
|
||||
DiagnosticFactory2<KtNamedDeclaration, CallableMemberDescriptor, CallableMemberDescriptor> PROPERTY_TYPE_MISMATCH_ON_OVERRIDE =
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_RETURN_TYPE);
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.diagnostics.rendering
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.platform.PlatformSpecificDiagnosticComponents
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
|
||||
data class DeclarationWithDiagnosticComponents(
|
||||
val declaration: DeclarationDescriptor,
|
||||
val diagnosticComponents: PlatformSpecificDiagnosticComponents
|
||||
) : Iterable<Any> {
|
||||
override fun iterator() =
|
||||
sequenceOf(declaration, diagnosticComponents).iterator()
|
||||
}
|
||||
|
||||
class AnnotationsWhitelistDescriptorRenderer(
|
||||
private val baseRenderer: DescriptorRenderer,
|
||||
private val toParameterRenderer: DescriptorRenderer.() -> DiagnosticParameterRenderer<DeclarationDescriptor>
|
||||
) : DiagnosticParameterRenderer<DeclarationWithDiagnosticComponents> {
|
||||
override fun render(obj: DeclarationWithDiagnosticComponents, renderingContext: RenderingContext): String {
|
||||
val (descriptor, diagnosticComponents) = obj
|
||||
return baseRenderer.withOptions {
|
||||
annotationFilter = { annotation ->
|
||||
diagnosticComponents.isNullabilityAnnotation(annotation, descriptor)
|
||||
}
|
||||
}.toParameterRenderer().render(descriptor, renderingContext)
|
||||
}
|
||||
}
|
||||
|
||||
fun DescriptorRenderer.withAnnotationsWhitelist(
|
||||
toParameterRenderer: DescriptorRenderer.() -> DiagnosticParameterRenderer<DeclarationDescriptor> = DescriptorRenderer::asRenderer
|
||||
) = AnnotationsWhitelistDescriptorRenderer(this, toParameterRenderer)
|
||||
+7
-4
@@ -84,7 +84,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(EXTENSION_FUNCTION_SHADOWED_BY_MEMBER_PROPERTY_WITH_INVOKE,
|
||||
"Extension function is shadowed by a member property ''{0}'' with {1}", NAME, COMPACT_WITH_MODIFIERS);
|
||||
|
||||
MAP.put(INACCESSIBLE_TYPE, "Type {0} is inaccessible in this context due to: {1}", RENDER_TYPE, commaSeparated(FQ_NAMES_IN_TYPES));
|
||||
MAP.put(INACCESSIBLE_TYPE, "Type {0} is inaccessible in this context due to: {1}", RENDER_TYPE, commaSeparated(
|
||||
FQ_NAMES_IN_TYPES_WITH_ANNOTATIONS));
|
||||
|
||||
MAP.put(REDECLARATION, "Conflicting declarations: {0}", commaSeparated(COMPACT_WITH_MODIFIERS));
|
||||
MAP.put(PACKAGE_OR_CLASSIFIER_REDECLARATION, "Redeclaration: {0}", STRING);
|
||||
@@ -762,7 +763,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(CANNOT_CHANGE_ACCESS_PRIVILEGE, "Cannot change access privilege ''{0}'' for ''{1}'' in ''{2}''", VISIBILITY, NAME, NAME);
|
||||
|
||||
MAP.put(RETURN_TYPE_MISMATCH_ON_OVERRIDE, "Return type of ''{0}'' is not a subtype of the return type of the overridden member ''{1}''",
|
||||
NAME, FQ_NAMES_IN_TYPES);
|
||||
NAME, FQ_NAMES_IN_TYPES_ANNOTATIONS_WHITELIST);
|
||||
MAP.put(RETURN_TYPE_MISMATCH_ON_INHERITANCE, "''{0}'' clashes with ''{1}'': return types are incompatible",
|
||||
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
|
||||
@@ -784,7 +785,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(PROPERTY_TYPE_MISMATCH_BY_DELEGATION, "Type of property ''{0}'' is not a subtype of overridden by delegation ''{1}''",
|
||||
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(VAR_OVERRIDDEN_BY_VAL, "Var-property {0} cannot be overridden by val-property {1}", FQ_NAMES_IN_TYPES, FQ_NAMES_IN_TYPES);
|
||||
MAP.put(VAR_OVERRIDDEN_BY_VAL, "Var-property {0} cannot be overridden by val-property {1}", FQ_NAMES_IN_TYPES,
|
||||
FQ_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(CONFLICTING_INHERITED_MEMBERS, "{0} inherits conflicting members: {1}", NAME, commaSeparated(FQ_NAMES_IN_TYPES));
|
||||
MAP.put(ABSTRACT_MEMBER_NOT_IMPLEMENTED, "{0} is not abstract and does not implement abstract member {1}", RENDER_CLASS_OR_OBJECT,
|
||||
@@ -921,7 +923,8 @@ public class DefaultErrorMessages {
|
||||
|
||||
MAP.put(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES,
|
||||
"Names of the parameter #{1} conflict in the following members of supertypes: ''{0}''. " +
|
||||
"This may cause problems when calling this function with named arguments.", commaSeparated(FQ_NAMES_IN_TYPES), TO_STRING);
|
||||
"This may cause problems when calling this function with named arguments.", commaSeparated(
|
||||
FQ_NAMES_IN_TYPES), TO_STRING);
|
||||
|
||||
MAP.put(NAME_FOR_AMBIGUOUS_PARAMETER, "Named argument is not allowed for a parameter with an ambiguous name");
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.newTable
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.newText
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -157,7 +158,25 @@ object Renderers {
|
||||
val RENDER_CLASS_OR_OBJECT_NAME = Renderer<ClassifierDescriptorWithTypeParameters> { it.renderKindWithName() }
|
||||
|
||||
@JvmField
|
||||
val RENDER_TYPE = SmartTypeRenderer(DescriptorRenderer.FQ_NAMES_IN_TYPES.withOptions { parameterNamesInFunctionalTypes = false })
|
||||
val RENDER_TYPE = SmartTypeRenderer(DescriptorRenderer.FQ_NAMES_IN_TYPES.withOptions {
|
||||
parameterNamesInFunctionalTypes = false
|
||||
})
|
||||
|
||||
@JvmField
|
||||
val RENDER_TYPE_WITH_ANNOTATIONS = SmartTypeRenderer(DescriptorRenderer.FQ_NAMES_IN_TYPES_WITH_ANNOTATIONS.withOptions {
|
||||
parameterNamesInFunctionalTypes = false
|
||||
})
|
||||
|
||||
@JvmField
|
||||
val TYPE_PROJECTION = Renderer<TypeProjection> { projection ->
|
||||
when {
|
||||
projection.isStarProjection -> "*"
|
||||
projection.projectionKind == Variance.INVARIANT ->
|
||||
RENDER_TYPE.render(projection.type, RenderingContext.of(projection.type))
|
||||
else ->
|
||||
"${projection.projectionKind} ${RENDER_TYPE.render(projection.type, RenderingContext.of(projection.type))}"
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val RENDER_POSITION_VARIANCE = Renderer { variance: Variance ->
|
||||
@@ -504,7 +523,10 @@ object Renderers {
|
||||
newText().normal(
|
||||
typeParameter.name.wrapIntoQuotes() +
|
||||
" cannot capture " +
|
||||
"${capturedTypeConstructor.projection.toString().wrapIntoQuotes()}. " +
|
||||
"${result.typeProjectionRenderer.render(
|
||||
capturedTypeConstructor.projection,
|
||||
RenderingContext.of(capturedTypeConstructor.projection)
|
||||
).wrapIntoQuotes()}. " +
|
||||
explanation
|
||||
)
|
||||
)
|
||||
@@ -527,11 +549,18 @@ object Renderers {
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderTypes(types: Collection<KotlinType>, context: RenderingContext) =
|
||||
StringUtil.join(types, { RENDER_TYPE.render(it, context) }, ", ")
|
||||
private fun renderTypes(
|
||||
types: Collection<KotlinType>,
|
||||
typeRenderer: DiagnosticParameterRenderer<KotlinType>,
|
||||
context: RenderingContext
|
||||
): String {
|
||||
return StringUtil.join(types, { typeRenderer.render(it, context) }, ", ")
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val RENDER_COLLECTION_OF_TYPES = ContextDependentRenderer<Collection<KotlinType>> { types, context -> renderTypes(types, context) }
|
||||
val RENDER_COLLECTION_OF_TYPES = ContextDependentRenderer<Collection<KotlinType>> { types, context ->
|
||||
renderTypes(types, RENDER_TYPE, context)
|
||||
}
|
||||
|
||||
enum class ConstraintSystemRenderingVerbosity {
|
||||
COMPACT,
|
||||
@@ -634,13 +663,13 @@ object Renderers {
|
||||
if (TypeUtils.noExpectedType(inferenceErrorData.expectedType)) {
|
||||
append(inferenceErrorData.expectedType)
|
||||
} else {
|
||||
append(RENDER_TYPE.render(inferenceErrorData.expectedType, context))
|
||||
append(RENDER_TYPE_WITH_ANNOTATIONS.render(inferenceErrorData.expectedType, context))
|
||||
}
|
||||
append("\nArgument types:\n")
|
||||
if (inferenceErrorData.receiverArgumentType != null) {
|
||||
append(RENDER_TYPE.render(inferenceErrorData.receiverArgumentType, context)).append(".")
|
||||
append(RENDER_TYPE_WITH_ANNOTATIONS.render(inferenceErrorData.receiverArgumentType, context)).append(".")
|
||||
}
|
||||
append("(").append(renderTypes(inferenceErrorData.valueArgumentsTypes, context)).append(")")
|
||||
append("(").append(renderTypes(inferenceErrorData.valueArgumentsTypes, RENDER_TYPE_WITH_ANNOTATIONS, context)).append(")")
|
||||
}
|
||||
|
||||
private fun String.wrapIntoQuotes(): String = "'$this'"
|
||||
@@ -662,6 +691,10 @@ object Renderers {
|
||||
@JvmField
|
||||
val FQ_NAMES_IN_TYPES = DescriptorRenderer.FQ_NAMES_IN_TYPES.asRenderer()
|
||||
@JvmField
|
||||
val FQ_NAMES_IN_TYPES_ANNOTATIONS_WHITELIST = DescriptorRenderer.FQ_NAMES_IN_TYPES_WITH_ANNOTATIONS.withAnnotationsWhitelist()
|
||||
@JvmField
|
||||
val FQ_NAMES_IN_TYPES_WITH_ANNOTATIONS = DescriptorRenderer.FQ_NAMES_IN_TYPES_WITH_ANNOTATIONS.asRenderer()
|
||||
@JvmField
|
||||
val COMPACT = DescriptorRenderer.COMPACT.asRenderer()
|
||||
@JvmField
|
||||
val COMPACT_WITHOUT_SUPERTYPES = DescriptorRenderer.COMPACT_WITHOUT_SUPERTYPES.asRenderer()
|
||||
|
||||
+6
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.Table
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.TextRenderer.TextElement;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeProjection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@@ -157,6 +158,11 @@ public class TabledDescriptorRenderer {
|
||||
return Renderers.RENDER_TYPE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DiagnosticParameterRenderer<TypeProjection> getTypeProjectionRenderer() {
|
||||
return Renderers.TYPE_PROJECTION;
|
||||
}
|
||||
|
||||
protected void renderText(TextRenderer textRenderer, StringBuilder result) {
|
||||
for (TextElement element : textRenderer.elements) {
|
||||
result.append(element.text);
|
||||
|
||||
+2
-2
@@ -77,7 +77,7 @@ private fun collectClassifiersFqNames(objectsToRender: Collection<Any?>): Set<Fq
|
||||
collectMentionedClassifiersFqNames(objectsToRender, this)
|
||||
}
|
||||
|
||||
private fun collectMentionedClassifiersFqNames(contextObjects: Collection<Any?>, result: MutableSet<FqNameUnsafe>) {
|
||||
private fun collectMentionedClassifiersFqNames(contextObjects: Iterable<Any?>, result: MutableSet<FqNameUnsafe>) {
|
||||
fun KotlinType.addMentionedTypeConstructor() {
|
||||
constructor.declarationDescriptor?.let { result.add(it.fqNameUnsafe) }
|
||||
}
|
||||
@@ -90,7 +90,7 @@ private fun collectMentionedClassifiersFqNames(contextObjects: Collection<Any?>,
|
||||
}
|
||||
}
|
||||
|
||||
contextObjects.filterIsInstance<Collection<*>>().forEach {
|
||||
contextObjects.filterIsInstance<Iterable<*>>().forEach {
|
||||
collectMentionedClassifiersFqNames(it, result)
|
||||
}
|
||||
contextObjects.filterIsInstance<ClassifierDescriptor>().forEach {
|
||||
|
||||
@@ -30,8 +30,10 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERR
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactoryWithPsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DeclarationWithDiagnosticComponents
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.platform.PlatformSpecificDiagnosticComponents
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractFakeOverride
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
|
||||
@@ -47,7 +49,8 @@ class OverrideResolver(
|
||||
private val trace: BindingTrace,
|
||||
private val overridesBackwardCompatibilityHelper: OverridesBackwardCompatibilityHelper,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val kotlinTypeRefiner: KotlinTypeRefiner
|
||||
private val kotlinTypeRefiner: KotlinTypeRefiner,
|
||||
private val platformSpecificDiagnosticComponents: PlatformSpecificDiagnosticComponents
|
||||
) {
|
||||
|
||||
fun check(c: TopDownAnalysisContext) {
|
||||
@@ -289,7 +292,9 @@ class OverrideResolver(
|
||||
override fun returnTypeMismatchOnOverride(overriding: CallableMemberDescriptor, overridden: CallableMemberDescriptor) {
|
||||
if (!typeMismatchError) {
|
||||
typeMismatchError = true
|
||||
trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden))
|
||||
trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(
|
||||
member, declared, DeclarationWithDiagnosticComponents(overridden, platformSpecificDiagnosticComponents)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user