diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index bbb47ac6875..958ac815abb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -949,6 +949,9 @@ public interface Errors { DiagnosticFactory1 ILLEGAL_SUSPEND_FUNCTION_CALL = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL = DiagnosticFactory0.create(ERROR); + DiagnosticFactory2 PLUGIN_ERROR = DiagnosticFactory2.create(ERROR); + DiagnosticFactory2 PLUGIN_WARNING = DiagnosticFactory2.create(WARNING); + DiagnosticFactory2 PLUGIN_INFO = DiagnosticFactory2.create(INFO); // Error sets ImmutableSet> UNRESOLVED_REFERENCE_DIAGNOSTICS = ImmutableSet.of( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/diagnosticUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/diagnosticUtils.kt index 909cf619942..25620490a20 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/diagnosticUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/diagnosticUtils.kt @@ -21,6 +21,8 @@ import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages +import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticRenderer import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtLambdaExpression @@ -159,4 +161,18 @@ inline fun reportOnDeclarationAs(trace: BindingTrace trace.report(what(it)) } ?: throw AssertionError("Declaration for $descriptor is expected to be ${T::class.simpleName}, actual declaration: $psiElement") } ?: throw AssertionError("No declaration for $descriptor") +} + +fun DiagnosticSink.reportFromPlugin(diagnostic: D, ext: DefaultErrorMessages.Extension) { + @Suppress("UNCHECKED_CAST") + val renderer = ext.map[diagnostic.factory] as? DiagnosticRenderer + ?: error("Renderer not found for diagnostic ${diagnostic.factory.name}") + + val text = renderer.render(diagnostic) + + when (diagnostic.severity) { + Severity.ERROR -> report(Errors.PLUGIN_ERROR.on(diagnostic.psiElement, diagnostic.factory.name, text)) + Severity.WARNING -> report(Errors.PLUGIN_WARNING.on(diagnostic.psiElement, diagnostic.factory.name, text)) + Severity.INFO -> report(Errors.PLUGIN_INFO.on(diagnostic.psiElement, diagnostic.factory.name, text)) + } } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index db710a6e774..bd3496eb5f6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -865,6 +865,10 @@ public class DefaultErrorMessages { MAP.put(ILLEGAL_SUSPEND_FUNCTION_CALL, "Suspend function ''{0}'' should be called only from a coroutine or another suspend function", NAME); MAP.put(ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL, "Restricted suspending functions can only invoke member or extension suspending functions on their restricted coroutine scope"); + MAP.put(PLUGIN_ERROR, "{0}: {1}", TO_STRING, TO_STRING); + MAP.put(PLUGIN_WARNING, "{0}: {1}", TO_STRING, TO_STRING); + MAP.put(PLUGIN_INFO, "{0}: {1}", TO_STRING, TO_STRING); + MAP.setImmutable(); for (Field field : Errors.class.getFields()) { diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableDeclarationChecker.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableDeclarationChecker.kt index 15288dc78a7..c9da521d0b9 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableDeclarationChecker.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableDeclarationChecker.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.android.parcel import org.jetbrains.kotlin.android.parcel.serializers.ParcelSerializer import org.jetbrains.kotlin.android.parcel.serializers.isParcelable +import org.jetbrains.kotlin.android.synthetic.diagnostic.DefaultErrorMessagesAndroid import org.jetbrains.kotlin.android.synthetic.diagnostic.ErrorsAndroid import org.jetbrains.kotlin.codegen.ClassBuilderMode import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker @@ -27,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.diagnostics.reportFromPlugin import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName @@ -82,7 +84,7 @@ class ParcelableDeclarationChecker : SimpleDeclarationChecker { if (method.isWriteToParcel() && declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD)) { val reportElement = declaration.modifierList?.getModifier(KtTokens.OVERRIDE_KEYWORD) ?: declaration.nameIdentifier ?: declaration - diagnosticHolder.report(ErrorsAndroid.OVERRIDING_WRITE_TO_PARCEL_IS_NOT_ALLOWED.on(reportElement)) + diagnosticHolder.reportFromPlugin(ErrorsAndroid.OVERRIDING_WRITE_TO_PARCEL_IS_NOT_ALLOWED.on(reportElement), DefaultErrorMessagesAndroid) } } @@ -97,14 +99,16 @@ class ParcelableDeclarationChecker : SimpleDeclarationChecker { && (declaration.hasDelegate() || bindingContext[BindingContext.BACKING_FIELD_REQUIRED, property] == true) && !property.annotations.hasAnnotation(TRANSIENT_FQNAME) ) { - diagnosticHolder.report(ErrorsAndroid.PROPERTY_WONT_BE_SERIALIZED.on(declaration.nameIdentifier ?: declaration)) + val reportElement = declaration.nameIdentifier ?: declaration + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PROPERTY_WONT_BE_SERIALIZED.on(reportElement), DefaultErrorMessagesAndroid) } // @JvmName is not applicable to property so we can check just the descriptor name if (property.name.asString() == "CREATOR" && property.findJvmFieldAnnotation() != null && containingClass.isCompanionObject) { val outerClass = containingClass.containingDeclaration as? ClassDescriptor if (outerClass != null && outerClass.isParcelize) { - diagnosticHolder.report(ErrorsAndroid.CREATOR_DEFINITION_IS_NOT_ALLOWED.on(declaration.nameIdentifier ?: declaration)) + val reportElement = declaration.nameIdentifier ?: declaration + diagnosticHolder.reportFromPlugin(ErrorsAndroid.CREATOR_DEFINITION_IS_NOT_ALLOWED.on(reportElement), DefaultErrorMessagesAndroid) } } } @@ -119,33 +123,35 @@ class ParcelableDeclarationChecker : SimpleDeclarationChecker { if (declaration !is KtClass || (declaration.isAnnotation() || declaration.isInterface())) { val reportElement = (declaration as? KtClassOrObject)?.nameIdentifier ?: declaration - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_SHOULD_BE_CLASS.on(reportElement)) + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_SHOULD_BE_CLASS.on(reportElement), DefaultErrorMessagesAndroid) return } if (declaration.isEnum()) { val reportElement = (declaration as? KtClass)?.nameIdentifier ?: declaration - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_SHOULD_BE_CLASS.on(reportElement)) + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_SHOULD_BE_CLASS.on(reportElement), DefaultErrorMessagesAndroid) return } val sealedOrAbstract = declaration.modifierList?.let { it.getModifier(KtTokens.ABSTRACT_KEYWORD) ?: it.getModifier(KtTokens.SEALED_KEYWORD) } if (sealedOrAbstract != null) { - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_SHOULD_BE_INSTANTIABLE.on(sealedOrAbstract)) + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_SHOULD_BE_INSTANTIABLE.on(sealedOrAbstract), DefaultErrorMessagesAndroid) } if (declaration.isInner()) { val reportElement = declaration.modifierList?.getModifier(KtTokens.INNER_KEYWORD) ?: declaration.nameIdentifier ?: declaration - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_CANT_BE_INNER_CLASS.on(reportElement)) + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_CANT_BE_INNER_CLASS.on(reportElement), DefaultErrorMessagesAndroid) } if (declaration.isLocal) { - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_CANT_BE_LOCAL_CLASS.on(declaration.nameIdentifier ?: declaration)) + val reportElement = declaration.nameIdentifier ?: declaration + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_CANT_BE_LOCAL_CLASS.on(reportElement), DefaultErrorMessagesAndroid) } val superTypes = TypeUtils.getAllSupertypes(descriptor.defaultType) if (superTypes.none { it.constructor.declarationDescriptor?.fqNameSafe == ANDROID_PARCELABLE_CLASS_FQNAME }) { - diagnosticHolder.report(ErrorsAndroid.NO_PARCELABLE_SUPERTYPE.on(declaration.nameIdentifier ?: declaration)) + val reportElement = declaration.nameIdentifier ?: declaration + diagnosticHolder.reportFromPlugin(ErrorsAndroid.NO_PARCELABLE_SUPERTYPE.on(reportElement), DefaultErrorMessagesAndroid) } for (supertypeEntry in declaration.superTypeListEntries) { @@ -154,15 +160,17 @@ class ParcelableDeclarationChecker : SimpleDeclarationChecker { val type = bindingContext[BindingContext.TYPE, supertypeEntry.typeReference] ?: continue if (type.isParcelable()) { val reportElement = supertypeEntry.byKeywordNode?.psi ?: delegateExpression - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_DELEGATE_IS_NOT_ALLOWED.on(reportElement)) + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_DELEGATE_IS_NOT_ALLOWED.on(reportElement), DefaultErrorMessagesAndroid) } } val primaryConstructor = declaration.primaryConstructor if (primaryConstructor == null && declaration.secondaryConstructors.isNotEmpty()) { - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_SHOULD_HAVE_PRIMARY_CONSTRUCTOR.on(declaration.nameIdentifier ?: declaration)) + val reportElement = declaration.nameIdentifier ?: declaration + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_SHOULD_HAVE_PRIMARY_CONSTRUCTOR.on(reportElement), DefaultErrorMessagesAndroid) } else if (primaryConstructor != null && primaryConstructor.valueParameters.isEmpty()) { - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_PRIMARY_CONSTRUCTOR_IS_EMPTY.on(declaration.nameIdentifier ?: declaration)) + val reportElement = declaration.nameIdentifier ?: declaration + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_PRIMARY_CONSTRUCTOR_IS_EMPTY.on(reportElement), DefaultErrorMessagesAndroid) } val typeMapper = KotlinTypeMapper( @@ -181,8 +189,9 @@ class ParcelableDeclarationChecker : SimpleDeclarationChecker { private fun checkParcelableClassProperty(parameter: KtParameter, diagnosticHolder: DiagnosticSink, typeMapper: KotlinTypeMapper) { if (!parameter.hasValOrVar()) { - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_CONSTRUCTOR_PARAMETER_SHOULD_BE_VAL_OR_VAR.on( - parameter.nameIdentifier ?: parameter)) + val reportElement = parameter.nameIdentifier ?: parameter + diagnosticHolder.reportFromPlugin( + ErrorsAndroid.PARCELABLE_CONSTRUCTOR_PARAMETER_SHOULD_BE_VAL_OR_VAR.on(reportElement), DefaultErrorMessagesAndroid) } val descriptor = typeMapper.bindingContext[BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter] ?: return @@ -196,8 +205,8 @@ class ParcelableDeclarationChecker : SimpleDeclarationChecker { } catch (e: IllegalArgumentException) { // get() throws IllegalArgumentException on unknown types - diagnosticHolder.report(ErrorsAndroid.PARCELABLE_TYPE_NOT_SUPPORTED.on( - parameter.typeReference ?: parameter.nameIdentifier ?: parameter)) + val reportElement = parameter.typeReference ?: parameter.nameIdentifier ?: parameter + diagnosticHolder.reportFromPlugin(ErrorsAndroid.PARCELABLE_TYPE_NOT_SUPPORTED.on(reportElement), DefaultErrorMessagesAndroid) } } } diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt index 4e3fbec660b..48a657b183b 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt @@ -117,7 +117,6 @@ class AndroidComponentRegistrar : ComponentRegistrar { ExpressionCodegenExtension.registerExtension(project, CliAndroidExtensionsExpressionCodegenExtension(isExperimental, globalCacheImpl)) StorageComponentContainerContributor.registerExtension(project, AndroidExtensionPropertiesComponentContainerContributor()) - Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME).registerExtension(DefaultErrorMessagesAndroid()) ClassBuilderInterceptorExtension.registerExtension(project, CliAndroidOnDestroyClassBuilderInterceptorExtension(globalCacheImpl)) PackageFragmentProviderExtension.registerExtension(project, CliAndroidPackageFragmentProviderExtension(isExperimental)) } diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/diagnostic/AndroidExtensionPropertiesCallChecker.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/diagnostic/AndroidExtensionPropertiesCallChecker.kt index 8535b359644..dbda50752ba 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/diagnostic/AndroidExtensionPropertiesCallChecker.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/diagnostic/AndroidExtensionPropertiesCallChecker.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.android.synthetic.res.AndroidSyntheticProperty import org.jetbrains.kotlin.android.synthetic.res.isErrorType import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.diagnostics.reportFromPlugin import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtExpression @@ -50,7 +51,7 @@ class AndroidExtensionPropertiesCallChecker : CallChecker { private fun DiagnosticSink.checkDeprecated(expression: KtExpression, packageDescriptor: AndroidSyntheticPackageFragmentDescriptor) { if (packageDescriptor.packageData.isDeprecated) { - report(SYNTHETIC_DEPRECATED_PACKAGE.on(expression)) + reportFromPlugin(SYNTHETIC_DEPRECATED_PACKAGE.on(expression), DefaultErrorMessagesAndroid) } } @@ -59,7 +60,7 @@ class AndroidExtensionPropertiesCallChecker : CallChecker { val type = property.errorType ?: return val warning = if (type.contains('.')) SYNTHETIC_UNRESOLVED_WIDGET_TYPE else SYNTHETIC_INVALID_WIDGET_TYPE - report(warning.on(expression, type)) + reportFromPlugin(warning.on(expression, type), DefaultErrorMessagesAndroid) } private fun DiagnosticSink.checkPartiallyDefinedResource( @@ -72,7 +73,7 @@ class AndroidExtensionPropertiesCallChecker : CallChecker { val expectedType = context.resolutionContext.expectedType if (!TypeUtils.noExpectedType(expectedType) && !expectedType.isMarkedNullable && !expectedType.isFlexible()) { - report(UNSAFE_CALL_ON_PARTIALLY_DEFINED_RESOURCE.on(calleeExpression)) + reportFromPlugin(UNSAFE_CALL_ON_PARTIALLY_DEFINED_RESOURCE.on(calleeExpression), DefaultErrorMessagesAndroid) return } @@ -80,7 +81,7 @@ class AndroidExtensionPropertiesCallChecker : CallChecker { val usage = outermostQualifiedExpression.parent if (usage is KtDotQualifiedExpression && usage.receiverExpression == outermostQualifiedExpression) { - report(UNSAFE_CALL_ON_PARTIALLY_DEFINED_RESOURCE.on(calleeExpression)) + reportFromPlugin(UNSAFE_CALL_ON_PARTIALLY_DEFINED_RESOURCE.on(calleeExpression), DefaultErrorMessagesAndroid) } } diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/diagnostic/DefaultErrorMessagesAndroid.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/diagnostic/DefaultErrorMessagesAndroid.kt index 806bf75c475..c7a441b12aa 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/diagnostic/DefaultErrorMessagesAndroid.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/diagnostic/DefaultErrorMessagesAndroid.kt @@ -20,70 +20,66 @@ import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap import org.jetbrains.kotlin.diagnostics.rendering.Renderers -class DefaultErrorMessagesAndroid : DefaultErrorMessages.Extension { - - private companion object { - val MAP = DiagnosticFactoryToRendererMap("Android") - - init { - MAP.put(ErrorsAndroid.SYNTHETIC_INVALID_WIDGET_TYPE, - "Widget has an invalid type ''{0}''. Please specify the fully qualified widget class name in XML", - Renderers.TO_STRING) - - MAP.put(ErrorsAndroid.SYNTHETIC_UNRESOLVED_WIDGET_TYPE, - "Widget has an unresolved type ''{0}'', and thus it was upcasted to ''android.view.View''", - Renderers.TO_STRING) - - MAP.put(ErrorsAndroid.SYNTHETIC_DEPRECATED_PACKAGE, - "Use properties from the build variant packages") - - MAP.put(ErrorsAndroid.UNSAFE_CALL_ON_PARTIALLY_DEFINED_RESOURCE, - "Potential NullPointerException. The resource is missing in some of layout versions") - - MAP.put(ErrorsAndroid.PARCELABLE_SHOULD_BE_CLASS, - "'Parcelable' should be a class") - - MAP.put(ErrorsAndroid.PARCELABLE_DELEGATE_IS_NOT_ALLOWED, - "Delegating 'Parcelable' is now allowed") - - MAP.put(ErrorsAndroid.PARCELABLE_SHOULD_NOT_BE_ENUM_CLASS, - "'Parcelable' should not be a 'enum class'") - - MAP.put(ErrorsAndroid.PARCELABLE_SHOULD_BE_INSTANTIABLE, - "'Parcelable' should not be a 'sealed' or 'abstract' class") - - MAP.put(ErrorsAndroid.PARCELABLE_CANT_BE_INNER_CLASS, - "'Parcelable' can't be an inner class") - - MAP.put(ErrorsAndroid.PARCELABLE_CANT_BE_LOCAL_CLASS, - "'Parcelable' can't be a local class") - - MAP.put(ErrorsAndroid.NO_PARCELABLE_SUPERTYPE, - "No 'Parcelable' supertype") - - MAP.put(ErrorsAndroid.PARCELABLE_SHOULD_HAVE_PRIMARY_CONSTRUCTOR, - "'Parcelable' should have a primary constructor") - - MAP.put(ErrorsAndroid.PARCELABLE_PRIMARY_CONSTRUCTOR_IS_EMPTY, - "The primary constructor is empty, no data will be serialized to 'Parcel'") - - MAP.put(ErrorsAndroid.PARCELABLE_CONSTRUCTOR_PARAMETER_SHOULD_BE_VAL_OR_VAR, - "'Parcelable' constructor parameter should be 'val' or 'var'") - - MAP.put(ErrorsAndroid.PROPERTY_WONT_BE_SERIALIZED, - "Property would not be serialized into a 'Parcel'. Add '@Transient' annotation to it") - - MAP.put(ErrorsAndroid.OVERRIDING_WRITE_TO_PARCEL_IS_NOT_ALLOWED, - "Overriding 'writeToParcel' is not allowed. Use 'Parceler' companion object instead.") - - MAP.put(ErrorsAndroid.CREATOR_DEFINITION_IS_NOT_ALLOWED, - "'CREATOR' definition is not allowed. Use 'Parceler' companion object instead.") - - MAP.put(ErrorsAndroid.PARCELABLE_TYPE_NOT_SUPPORTED, - "Type is not directly supported by 'Parcelize'. " + - "Annotate the parameter type with '@RawValue' if you want it to be serialized using 'writeValue()'") - } - } - +object DefaultErrorMessagesAndroid : DefaultErrorMessages.Extension { + private val MAP = DiagnosticFactoryToRendererMap("Android") override fun getMap() = MAP + + init { + MAP.put(ErrorsAndroid.SYNTHETIC_INVALID_WIDGET_TYPE, + "Widget has an invalid type ''{0}''. Please specify the fully qualified widget class name in XML", + Renderers.TO_STRING) + + MAP.put(ErrorsAndroid.SYNTHETIC_UNRESOLVED_WIDGET_TYPE, + "Widget has an unresolved type ''{0}'', and thus it was upcasted to ''android.view.View''", + Renderers.TO_STRING) + + MAP.put(ErrorsAndroid.SYNTHETIC_DEPRECATED_PACKAGE, + "Use properties from the build variant packages") + + MAP.put(ErrorsAndroid.UNSAFE_CALL_ON_PARTIALLY_DEFINED_RESOURCE, + "Potential NullPointerException. The resource is missing in some of layout versions") + + MAP.put(ErrorsAndroid.PARCELABLE_SHOULD_BE_CLASS, + "'Parcelable' should be a class") + + MAP.put(ErrorsAndroid.PARCELABLE_DELEGATE_IS_NOT_ALLOWED, + "Delegating 'Parcelable' is now allowed") + + MAP.put(ErrorsAndroid.PARCELABLE_SHOULD_NOT_BE_ENUM_CLASS, + "'Parcelable' should not be a 'enum class'") + + MAP.put(ErrorsAndroid.PARCELABLE_SHOULD_BE_INSTANTIABLE, + "'Parcelable' should not be a 'sealed' or 'abstract' class") + + MAP.put(ErrorsAndroid.PARCELABLE_CANT_BE_INNER_CLASS, + "'Parcelable' can't be an inner class") + + MAP.put(ErrorsAndroid.PARCELABLE_CANT_BE_LOCAL_CLASS, + "'Parcelable' can't be a local class") + + MAP.put(ErrorsAndroid.NO_PARCELABLE_SUPERTYPE, + "No 'Parcelable' supertype") + + MAP.put(ErrorsAndroid.PARCELABLE_SHOULD_HAVE_PRIMARY_CONSTRUCTOR, + "'Parcelable' should have a primary constructor") + + MAP.put(ErrorsAndroid.PARCELABLE_PRIMARY_CONSTRUCTOR_IS_EMPTY, + "The primary constructor is empty, no data will be serialized to 'Parcel'") + + MAP.put(ErrorsAndroid.PARCELABLE_CONSTRUCTOR_PARAMETER_SHOULD_BE_VAL_OR_VAR, + "'Parcelable' constructor parameter should be 'val' or 'var'") + + MAP.put(ErrorsAndroid.PROPERTY_WONT_BE_SERIALIZED, + "Property would not be serialized into a 'Parcel'. Add '@Transient' annotation to it") + + MAP.put(ErrorsAndroid.OVERRIDING_WRITE_TO_PARCEL_IS_NOT_ALLOWED, + "Overriding 'writeToParcel' is not allowed. Use 'Parceler' companion object instead.") + + MAP.put(ErrorsAndroid.CREATOR_DEFINITION_IS_NOT_ALLOWED, + "'CREATOR' definition is not allowed. Use 'Parceler' companion object instead.") + + MAP.put(ErrorsAndroid.PARCELABLE_TYPE_NOT_SUPPORTED, + "Type is not directly supported by 'Parcelize'. " + + "Annotate the parameter type with '@RawValue' if you want it to be serialized using 'writeValue()'") + } } \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/constructors.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/constructors.kt index a900a978953..757c667725d 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/constructors.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/constructors.kt @@ -10,7 +10,7 @@ class A : Parcelable class B(val firstName: String, val secondName: String) : Parcelable @Parcelize -class C(val firstName: String, secondName: String) : Parcelable +class C(val firstName: String, secondName: String) : Parcelable @Parcelize class D(val firstName: String, vararg val secondName: String) : Parcelable @@ -21,7 +21,7 @@ class E(val firstName: String, val secondName: String) : Parcelable { } @Parcelize -class F : Parcelable { +class F : Parcelable { constructor(a: String) { println(a) } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/customCreator.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/customCreator.kt index e821a32d50b..a7937556d1e 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/customCreator.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/customCreator.kt @@ -8,7 +8,7 @@ import android.os.Parcel class A(val a: String) : Parcelable { companion object { @JvmField - val CREATOR = object : Parcelable.Creator { + val CREATOR = object : Parcelable.Creator { override fun createFromParcel(source: Parcel): A = A("") override fun newArray(size: Int) = arrayOfNulls(size) } diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/customWriteToParcel.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/customWriteToParcel.kt index 73eaeacdf03..fcc34791881 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/customWriteToParcel.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/customWriteToParcel.kt @@ -6,16 +6,16 @@ import android.os.Parcel @Parcelize class A(val a: String) : Parcelable { - override fun writeToParcel(p: Parcel?, flags: Int) {} + override fun writeToParcel(p: Parcel?, flags: Int) {} override fun describeContents() = 0 } @Parcelize class B(val a: String) : Parcelable { - override fun writeToParcel(p: Parcel?, flags: Int) {} + override fun writeToParcel(p: Parcel?, flags: Int) {} } @Parcelize class C(val a: String) : Parcelable { - override fun writeToParcel(p: Parcel, flags: Int) {} + override fun writeToParcel(p: Parcel, flags: Int) {} } \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/delegate.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/delegate.kt index 6dbb00a48ee..2d3cb008e27 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/delegate.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/delegate.kt @@ -10,4 +10,4 @@ open class Delegate : Parcelable { } @Parcelize -class Test : Parcelable by Delegate() \ No newline at end of file +class Test : Parcelable by Delegate() \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/emptyPrimaryConstructor.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/emptyPrimaryConstructor.kt index 15049851d56..7c605d3acd0 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/emptyPrimaryConstructor.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/emptyPrimaryConstructor.kt @@ -7,4 +7,4 @@ import android.os.Parcelable class User : Parcelable @Parcelize -class User2() : Parcelable \ No newline at end of file +class User2() : Parcelable \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/modality.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/modality.kt index 43c46039215..d7797a59a04 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/modality.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/modality.kt @@ -10,22 +10,22 @@ open class Open(val foo: String) : Parcelable class Final(val foo: String) : Parcelable @Parcelize -abstract class Abstract(val foo: String) : Parcelable +abstract class Abstract(val foo: String) : Parcelable @Parcelize -sealed class Sealed(val foo: String) : Parcelable { +sealed class Sealed(val foo: String) : Parcelable { class X : Sealed("") } class Outer { @Parcelize - inner class Inner(val foo: String) : Parcelable + inner class Inner(val foo: String) : Parcelable } fun foo() { @Parcelize - object : Parcelable {} + object : Parcelable {} @Parcelize - class Local {} + class Local {} } \ No newline at end of file diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/properties.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/properties.kt index d695cf42f79..09d70383c8a 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/properties.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/properties.kt @@ -5,11 +5,11 @@ import android.os.Parcelable @Parcelize class A(val firstName: String) : Parcelable { - val secondName: String = "" + val secondName: String = "" - val delegated by lazy { "" } + val delegated by lazy { "" } - lateinit var lateinit: String + lateinit var lateinit: String val customGetter: String get() = "" diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/unsupportedType.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/unsupportedType.kt index 485c1ca2c9a..1f14479bf00 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/unsupportedType.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/unsupportedType.kt @@ -7,9 +7,9 @@ import android.os.Parcelable @Parcelize class User( val a: String, - val b: Any, - val c: Any?, - val d: Map, + val b: Any, + val c: Any?, + val d: Map, val e: @RawValue Any?, val f: @RawValue Map, val g: Map, diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/withoutParcelableSupertype.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/withoutParcelableSupertype.kt index 98e3cdb416d..9eed0adeb3a 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/withoutParcelableSupertype.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/withoutParcelableSupertype.kt @@ -4,7 +4,7 @@ import kotlinx.android.parcel.Parcelize import android.os.Parcelable @Parcelize -class Without(val firstName: String, val secondName: String, val age: Int) +class Without(val firstName: String, val secondName: String, val age: Int) @Parcelize class With(val firstName: String, val secondName: String, val age: Int) : Parcelable diff --git a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/wrongAnnotationTarget.kt b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/wrongAnnotationTarget.kt index a37b8a62e15..fadea294e3c 100644 --- a/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/wrongAnnotationTarget.kt +++ b/plugins/android-extensions/android-extensions-idea/testData/android/parcel/checker/wrongAnnotationTarget.kt @@ -4,22 +4,22 @@ import kotlinx.android.parcel.Parcelize import android.os.Parcelable @Parcelize -interface Intf : Parcelable +interface Intf : Parcelable @Parcelize -object Obj +object Obj class A { @Parcelize - companion object { + companion object { fun foo() {} } } @Parcelize -enum class Enum { +enum class Enum { WHITE, BLACK } @Parcelize -annotation class Anno \ No newline at end of file +annotation class Anno \ No newline at end of file diff --git a/plugins/noarg/noarg-cli/src/NoArgPlugin.kt b/plugins/noarg/noarg-cli/src/NoArgPlugin.kt index 65ed107995d..ee58a084422 100644 --- a/plugins/noarg/noarg-cli/src/NoArgPlugin.kt +++ b/plugins/noarg/noarg-cli/src/NoArgPlugin.kt @@ -17,8 +17,6 @@ package org.jetbrains.kotlin.noarg import com.intellij.mock.MockProject -import com.intellij.openapi.extensions.Extensions -import org.jetbrains.kotlin.noarg.diagnostic.DefaultErrorMessagesNoArg import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension import org.jetbrains.kotlin.compiler.plugin.CliOption import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException @@ -28,7 +26,6 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.useInstance -import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor import org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor.Companion.SUPPORTED_PRESETS import org.jetbrains.kotlin.noarg.NoArgConfigurationKeys.ANNOTATION @@ -84,7 +81,6 @@ class NoArgComponentRegistrar : ComponentRegistrar { } if (annotations.isEmpty()) return - Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME).registerExtension(DefaultErrorMessagesNoArg()) StorageComponentContainerContributor.registerExtension(project, CliNoArgComponentContainerContributor(annotations)) val invokeInitializers = configuration[INVOKE_INITIALIZERS] ?: false diff --git a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt index 9946a10d5f6..918ca8984d0 100644 --- a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt +++ b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.diagnostics.reportFromPlugin import org.jetbrains.kotlin.extensions.AnnotationBasedExtension import org.jetbrains.kotlin.noarg.NO_ARG_CLASS_KEY import org.jetbrains.kotlin.psi.KtClass @@ -54,7 +55,7 @@ abstract class AbstractNoArgDeclarationChecker : DeclarationChecker, AnnotationB val superClass = descriptor.getSuperClassOrAny() if (superClass.constructors.none { it.isNoArgConstructor() } && !superClass.hasSpecialAnnotation(declaration)) { val reportTarget = declaration.nameIdentifier ?: declaration.getClassOrInterfaceKeyword() ?: declaration - diagnosticHolder.report(ErrorsNoArg.NO_NOARG_CONSTRUCTOR_IN_SUPERCLASS.on(reportTarget)) + diagnosticHolder.reportFromPlugin(ErrorsNoArg.NO_NOARG_CONSTRUCTOR_IN_SUPERCLASS.on(reportTarget), DefaultErrorMessagesNoArg) } } } diff --git a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/DefaultErrorMessagesNoArg.kt b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/DefaultErrorMessagesNoArg.kt index 6de21ade399..baea39626f0 100644 --- a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/DefaultErrorMessagesNoArg.kt +++ b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/DefaultErrorMessagesNoArg.kt @@ -19,14 +19,11 @@ package org.jetbrains.kotlin.noarg.diagnostic import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap -class DefaultErrorMessagesNoArg : DefaultErrorMessages.Extension { - private companion object { - val MAP = DiagnosticFactoryToRendererMap("AnnotationProcessing") - - init { - MAP.put(ErrorsNoArg.NO_NOARG_CONSTRUCTOR_IN_SUPERCLASS, "Zero-argument constructor was not found in the superclass") - } - } - +object DefaultErrorMessagesNoArg : DefaultErrorMessages.Extension { + private val MAP = DiagnosticFactoryToRendererMap("AnnotationProcessing") override fun getMap() = MAP + + init { + MAP.put(ErrorsNoArg.NO_NOARG_CONSTRUCTOR_IN_SUPERCLASS, "Zero-argument constructor was not found in the superclass") + } } \ No newline at end of file diff --git a/plugins/plugins-tests/tests/org/jetbrains/kotlin/noarg/AbstractBlackBoxCodegenTestForNoArg.kt b/plugins/plugins-tests/tests/org/jetbrains/kotlin/noarg/AbstractBlackBoxCodegenTestForNoArg.kt index 2af1cbe09d5..9897322b370 100644 --- a/plugins/plugins-tests/tests/org/jetbrains/kotlin/noarg/AbstractBlackBoxCodegenTestForNoArg.kt +++ b/plugins/plugins-tests/tests/org/jetbrains/kotlin/noarg/AbstractBlackBoxCodegenTestForNoArg.kt @@ -16,18 +16,13 @@ package org.jetbrains.kotlin.noarg -import com.intellij.openapi.extensions.Extensions import org.jetbrains.kotlin.codegen.AbstractBlackBoxCodegenTest import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension -import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor.Companion.registerExtension import org.jetbrains.kotlin.noarg.AbstractBytecodeListingTestForNoArg.Companion.NOARG_ANNOTATIONS -import org.jetbrains.kotlin.noarg.diagnostic.DefaultErrorMessagesNoArg abstract class AbstractBlackBoxCodegenTestForNoArg : AbstractBlackBoxCodegenTest() { override fun loadMultiFiles(files: MutableList) { - Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME).registerExtension(DefaultErrorMessagesNoArg()) - val project = myEnvironment.project registerExtension(project, CliNoArgComponentContainerContributor(NOARG_ANNOTATIONS)) val invokeInitializers = files.any { "// INVOKE_INITIALIZERS" in it.content } diff --git a/plugins/plugins-tests/tests/org/jetbrains/kotlin/noarg/AbstractBytecodeListingTestForNoArg.kt b/plugins/plugins-tests/tests/org/jetbrains/kotlin/noarg/AbstractBytecodeListingTestForNoArg.kt index b5f3be9ed22..5995160c3a2 100644 --- a/plugins/plugins-tests/tests/org/jetbrains/kotlin/noarg/AbstractBytecodeListingTestForNoArg.kt +++ b/plugins/plugins-tests/tests/org/jetbrains/kotlin/noarg/AbstractBytecodeListingTestForNoArg.kt @@ -16,13 +16,10 @@ package org.jetbrains.kotlin.noarg -import com.intellij.openapi.extensions.Extensions import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.AbstractBytecodeListingTest import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension -import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor -import org.jetbrains.kotlin.noarg.diagnostic.DefaultErrorMessagesNoArg abstract class AbstractBytecodeListingTestForNoArg : AbstractBytecodeListingTest() { internal companion object { @@ -30,8 +27,6 @@ abstract class AbstractBytecodeListingTestForNoArg : AbstractBytecodeListingTest } override fun setupEnvironment(environment: KotlinCoreEnvironment) { - Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME).registerExtension(DefaultErrorMessagesNoArg()) - val project = environment.project StorageComponentContainerContributor.registerExtension(project, CliNoArgComponentContainerContributor(NOARG_ANNOTATIONS)) ExpressionCodegenExtension.registerExtension(project, NoArgExpressionCodegenExtension(false))