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:
Pavel Kirpichenkov
2019-09-20 17:01:09 +03:00
parent 2a99687a95
commit b7e5d9faae
54 changed files with 1047 additions and 46 deletions
@@ -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);
@@ -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)
@@ -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()
@@ -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);
@@ -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)
))
}
}